Skip to content

Commit

Permalink
creating new hike vehicle and using less priority values for foot fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
karussell committed Jun 6, 2016
1 parent 7b89e4d commit 500dcfd
Show file tree
Hide file tree
Showing 11 changed files with 472 additions and 45 deletions.
1 change: 1 addition & 0 deletions core/files/changelog.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
0.7
added snapped points to output JSON for every path
the foot routing is now much smoother and only considers safe paths, to use beautiful roads (i.e. prefer hiking routes etc) use the new 'hike' profiles, see #633
vehicle constants have moved to FlagEncoderFactory
several constants changed to under score notation see #719 with a few breaking changes, e.g. use lower case names for flag encoders or jsonp_allowed instead of the jsonpAllowed annotation
moving all string parameter constants into the Parameters class
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,25 +32,27 @@ public FlagEncoder createFlagEncoder( String name, PMap configuration )
if (name.equals(CAR))
return new CarFlagEncoder(configuration);

else if (name.equals(BIKE))
if (name.equals(BIKE))
return new BikeFlagEncoder(configuration);

else if (name.equals(BIKE2))
if (name.equals(BIKE2))
return new Bike2WeightFlagEncoder(configuration);

else if (name.equals(RACINGBIKE))
if (name.equals(RACINGBIKE))
return new RacingBikeFlagEncoder(configuration);

else if (name.equals(MOUNTAINBIKE))
if (name.equals(MOUNTAINBIKE))
return new MountainBikeFlagEncoder(configuration);

else if (name.equals(FOOT))
if (name.equals(FOOT))
return new FootFlagEncoder(configuration);

else if (name.equals(MOTORCYCLE))
if (name.equals(HIKE))
return new HikeFlagEncoder(configuration);

if (name.equals(MOTORCYCLE))
return new MotorcycleFlagEncoder(configuration);

else
throw new IllegalArgumentException("entry in encoder list not supported " + name);
throw new IllegalArgumentException("entry in encoder list not supported " + name);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public interface FlagEncoderFactory
final String RACINGBIKE = "racingbike";
final String MOUNTAINBIKE = "mtb";
final String FOOT = "foot";
final String HIKE = "hike";
final String MOTORCYCLE = "motorcycle";
final FlagEncoderFactory DEFAULT = new DefaultFlagEncoderFactory();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@
import static com.graphhopper.routing.util.PriorityCode.*;

/**
* Defines bit layout for pedestrians (speed, access, surface, ...).
* Defines bit layout for pedestrians (speed, access, surface, ...). Here we put a penalty on unsafe
* roads only. If you wish to also prefer routes due to beauty like hiking routes use the
* HikeFlagEncoder instead.
* <p>
* @author Peter Karich
* @author Nop
Expand All @@ -41,13 +43,13 @@ public class FootFlagEncoder extends AbstractFlagEncoder
static final int FERRY_SPEED = 10;
private EncodedValue priorityWayEncoder;
private EncodedValue relationCodeEncoder;
protected HashSet<String> sidewalks = new HashSet<String>(5);
protected HashSet<String> sidewalksNo = new HashSet<String>(5);
private final Set<String> safeHighwayTags = new HashSet<String>();
private final Set<String> allowedHighwayTags = new HashSet<String>();
private final Set<String> avoidHighwayTags = new HashSet<String>();
protected HashSet<String> sidewalkValues = new HashSet<String>(5);
protected HashSet<String> sidewalksNoValues = new HashSet<String>(5);
final Set<String> safeHighwayTags = new HashSet<String>();
final Set<String> allowedHighwayTags = new HashSet<String>();
final Set<String> avoidHighwayTags = new HashSet<String>();
// convert network tag of hiking routes into a way route code
private final Map<String, Integer> hikingNetworkToCode = new HashMap<String, Integer>();
final Map<String, Integer> hikingNetworkToCode = new HashMap<String, Integer>();

/**
* Should be only instantiated via EncodingManager
Expand All @@ -59,10 +61,8 @@ public FootFlagEncoder()

public FootFlagEncoder( PMap properties )
{
this(
(int) properties.getLong("speedBits", 4),
properties.getDouble("speedFactor", 1)
);
this((int) properties.getLong("speedBits", 4),
properties.getDouble("speedFactor", 1));
this.properties = properties;
this.setBlockFords(properties.getBool("blockFords", true));
}
Expand All @@ -87,15 +87,15 @@ public FootFlagEncoder( int speedBits, double speedFactor )
intendedValues.add("official");
intendedValues.add("permissive");

sidewalksNo.add("no");
sidewalksNo.add("none");
sidewalksNoValues.add("no");
sidewalksNoValues.add("none");
// see #712
sidewalksNo.add("separate");
sidewalksNoValues.add("separate");

sidewalks.add("yes");
sidewalks.add("both");
sidewalks.add("left");
sidewalks.add("right");
sidewalkValues.add("yes");
sidewalkValues.add("both");
sidewalkValues.add("left");
sidewalkValues.add("right");

setBlockByDefault(false);
potentialBarriers.add("gate");
Expand Down Expand Up @@ -128,10 +128,10 @@ public FootFlagEncoder( int speedBits, double speedFactor )
// disallowed in some countries
//allowedHighwayTags.add("bridleway");

hikingNetworkToCode.put("iwn", BEST.getValue());
hikingNetworkToCode.put("nwn", BEST.getValue());
hikingNetworkToCode.put("rwn", VERY_NICE.getValue());
hikingNetworkToCode.put("lwn", VERY_NICE.getValue());
hikingNetworkToCode.put("iwn", UNCHANGED.getValue());
hikingNetworkToCode.put("nwn", UNCHANGED.getValue());
hikingNetworkToCode.put("rwn", UNCHANGED.getValue());
hikingNetworkToCode.put("lwn", UNCHANGED.getValue());

maxPossibleSpeed = FERRY_SPEED;

Expand All @@ -141,7 +141,7 @@ public FootFlagEncoder( int speedBits, double speedFactor )
@Override
public int getVersion()
{
return 1;
return 2;
}

@Override
Expand Down Expand Up @@ -235,7 +235,7 @@ public long acceptWay( OSMWay way )
return 0;
}

if (way.hasTag("sidewalk", sidewalks))
if (way.hasTag("sidewalk", sidewalkValues))
return acceptBit;

// no need to evaluate ferries or fords - already included here
Expand Down Expand Up @@ -271,6 +271,8 @@ public long handleRelationTags( OSMRelation relation, long oldRelationFlags )
Integer val = hikingNetworkToCode.get(relation.getTag("network"));
if (val != null)
code = val;
else
code = hikingNetworkToCode.get("lwn");
} else if (relation.hasTag("route", "ferry"))
{
code = PriorityCode.AVOID_IF_POSSIBLE.getValue();
Expand Down Expand Up @@ -365,17 +367,15 @@ void collect( OSMWay way, TreeMap<Double, Integer> weightToPrioMap )
weightToPrioMap.put(40d, PREFER.getValue());
if (way.hasTag("tunnel", intendedValues))
{
if (way.hasTag("sidewalk", sidewalksNo))
weightToPrioMap.put(40d, REACH_DEST.getValue());
if (way.hasTag("sidewalk", sidewalksNoValues))
weightToPrioMap.put(40d, AVOID_IF_POSSIBLE.getValue());
else
weightToPrioMap.put(40d, UNCHANGED.getValue());
}
} else if (maxSpeed > 50 || avoidHighwayTags.contains(highway))
{
if (way.hasTag("sidewalk", sidewalksNo))
weightToPrioMap.put(45d, WORST.getValue());
else
weightToPrioMap.put(45d, REACH_DEST.getValue());
if (!way.hasTag("sidewalk", sidewalkValues))
weightToPrioMap.put(45d, AVOID_IF_POSSIBLE.getValue());
}

if (way.hasTag("bicycle", "official") || way.hasTag("bicycle", "designated"))
Expand Down
164 changes: 164 additions & 0 deletions core/src/main/java/com/graphhopper/routing/util/HikeFlagEncoder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
/*
* Licensed to GraphHopper GmbH under one or more contributor
* license agreements. See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*
* GraphHopper GmbH licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.graphhopper.routing.util;

import com.graphhopper.reader.OSMWay;
import com.graphhopper.util.PMap;

import java.util.*;

import static com.graphhopper.routing.util.PriorityCode.*;

/**
* Defines bit layout for hiking
*
* @author Peter Karich
*/
public class HikeFlagEncoder extends FootFlagEncoder
{
/**
* Should be only instantiated via EncodingManager
*/
public HikeFlagEncoder()
{
this(4, 1);
}

public HikeFlagEncoder( PMap properties )
{
this((int) properties.getLong("speedBits", 4),
properties.getDouble("speedFactor", 1));
this.properties = properties;
this.setBlockFords(properties.getBool("blockFords", true));
}

public HikeFlagEncoder( String propertiesStr )
{
this(new PMap(propertiesStr));
}

public HikeFlagEncoder( int speedBits, double speedFactor )
{
super(speedBits, speedFactor);

hikingNetworkToCode.put("iwn", BEST.getValue());
hikingNetworkToCode.put("nwn", BEST.getValue());
hikingNetworkToCode.put("rwn", VERY_NICE.getValue());
hikingNetworkToCode.put("lwn", VERY_NICE.getValue());
}

@Override
public int getVersion()
{
return 1;
}

@Override
public long acceptWay( OSMWay way )
{
String highwayValue = way.getTag("highway");
if (highwayValue == null)
{
if (way.hasTag("route", ferries))
{
String footTag = way.getTag("foot");
if (footTag == null || "yes".equals(footTag))
return acceptBit | ferryBit;
}

// special case not for all acceptedRailways, only platform
if (way.hasTag("railway", "platform"))
return acceptBit;

return 0;
}

// hiking allows all sac_scale values
// String sacScale = way.getTag("sac_scale");
if (way.hasTag("sidewalk", sidewalkValues))
return acceptBit;

// no need to evaluate ferries or fords - already included here
if (way.hasTag("foot", intendedValues))
return acceptBit;

if (!allowedHighwayTags.contains(highwayValue))
return 0;

if (way.hasTag("motorroad", "yes"))
return 0;

// do not get our feet wet, "yes" is already included above
if (isBlockFords() && (way.hasTag("highway", "ford") || way.hasTag("ford")))
return 0;

// check access restrictions
if (way.hasTag(restrictions, restrictedValues) && !conditionalTagsInspector.isRestrictedWayConditionallyPermitted(way))
return 0;

if (conditionalTagsInspector.isPermittedWayConditionallyRestricted(way))
return 0;
else
return acceptBit;
}

@Override
void collect( OSMWay way, TreeMap<Double, Integer> weightToPrioMap )
{
String highway = way.getTag("highway");
if (way.hasTag("foot", "designated"))
weightToPrioMap.put(100d, PREFER.getValue());

double maxSpeed = getMaxSpeed(way);
if (safeHighwayTags.contains(highway) || maxSpeed > 0 && maxSpeed <= 20)
{
weightToPrioMap.put(40d, PREFER.getValue());
if (way.hasTag("tunnel", intendedValues))
{
if (way.hasTag("sidewalk", sidewalksNoValues))
weightToPrioMap.put(40d, REACH_DEST.getValue());
else
weightToPrioMap.put(40d, UNCHANGED.getValue());
}
} else if (maxSpeed > 50 || avoidHighwayTags.contains(highway))
{
if (way.hasTag("sidewalk", sidewalksNoValues))
weightToPrioMap.put(45d, WORST.getValue());
else
weightToPrioMap.put(45d, REACH_DEST.getValue());
}

if (way.hasTag("bicycle", "official") || way.hasTag("bicycle", "designated"))
weightToPrioMap.put(44d, AVOID_IF_POSSIBLE.getValue());
}

@Override
public boolean supports( Class<?> feature )
{
if (super.supports(feature))
return true;

return PriorityWeighting.class.isAssignableFrom(feature);
}

@Override
public String toString()
{
return "hike";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ public void testSidewalkNo()

boolean testAlsoCH = false, is3D = false;
runAlgo(testCollector, "files/map-sidewalk-no.osm.gz", "target/graph-sidewalkno",
list, "foot", testAlsoCH, "foot", "fastest", is3D);
list, "hike", testAlsoCH, "hike", "fastest", is3D);

assertEquals(testCollector.toString(), 0, testCollector.errors.size());
}
Expand Down Expand Up @@ -335,15 +335,15 @@ public void testMonacoFoot3D()
}

@Test
public void testNorthBayreuthFootFastestAnd3D()
public void testNorthBayreuthHikeFastestAnd3D()
{
List<OneRun> list = new ArrayList<OneRun>();
// prefer hiking route 'Teufelsloch Unterwaiz' and 'Rotmain-Wanderweg'
list.add(new OneRun(49.974972, 11.515657, 49.991022, 11.512299, 2365, 66));
// prefer hiking route 'Markgrafenweg Bayreuth Kulmbach' but avoid tertiary highway from Pechgraben
list.add(new OneRun(49.990967, 11.545258, 50.023182, 11.555386, 5636, 97));
runAlgo(testCollector, "files/north-bayreuth.osm.gz", "target/north-bayreuth-gh",
list, "foot", true, "foot", "fastest", true);
list, "hike", true, "hike", "fastest", true);
assertEquals(testCollector.toString(), 0, testCollector.errors.size());
}

Expand Down
Loading

0 comments on commit 500dcfd

Please sign in to comment.