Skip to content

Commit

Permalink
Access refactoring (#1436)
Browse files Browse the repository at this point in the history
* access refactoring

* move TagParser into separate file, added javadocs
  • Loading branch information
karussell committed Feb 19, 2019
1 parent b8c64be commit 2d93aa0
Show file tree
Hide file tree
Showing 42 changed files with 663 additions and 620 deletions.
10 changes: 8 additions & 2 deletions core/files/changelog.txt
@@ -1,15 +1,21 @@
0.12
access refactoring #1436 that moves AccessValue into SpatialRule.Access
refactoring of EncodingManager to use builder pattern. Migration should be simple. Replace new EncodingManager with EncodingManager.create
EncodingManager.supports renames to hasEncoder
big refactoring #1447: to increase 64bit limit of flags, make reverse direction handling easier, to allow shared EncodedValues,
remove reverseFlags method, much simpler property access, simplify FlagEncoder (maybe even deprecate this interface at a later stage)
moved shp-reader into separate repository: https://github.com/graphhopper/graphhopper-reader-shp

0.11
web resources for dropwizard web framework (no servlets anymore)
web resources for dropwizard web framework (no servlets anymore) #1108
prefix -Dgraphhopper. for command line arguments necessary, see docs/web/quickstart.md or docs/core/quickstart-from-source.md#running--debbuging-with-intellij for details
delegated reading properties to dropwizard, i.e. the new format yml is not read again in GraphHopper.init
changed file format for landmarks #1376
convert properties into new yml format via: https://gist.github.com/karussell/dbc9b4c455bca98b6a38e4a160e23bf8

0.10
introduce path details
added handcoded API java client to this repository

0.9
remove war bundling support #297
Expand Down
Expand Up @@ -63,9 +63,6 @@ public abstract class AbstractFlagEncoder implements FlagEncoder {
protected BooleanEncodedValue accessEnc;
protected BooleanEncodedValue roundaboutEnc;
protected DecimalEncodedValue speedEncoder;
// bit to signal that way is accepted
protected long acceptBit;
protected long ferryBit;
protected PMap properties;
// This value determines the maximal possible speed of any road regardless the maxspeed value
// lower values allow more compact representation of the routing graph
Expand Down Expand Up @@ -173,11 +170,6 @@ public void createEncodedValues(List<EncodedValue> registerNewEncodedValue, Stri
registerNewEncodedValue.add(accessEnc = new SimpleBooleanEncodedValue(prefix + "access", true));
roundaboutEnc = getBooleanEncodedValue(EncodingManager.ROUNDABOUT);
encoderBit = 1L << index;

// define internal flags for parsing
index *= 2;
acceptBit = 1L << index;
ferryBit = 2L << index;
}

/**
Expand All @@ -201,13 +193,13 @@ public int defineRelationBits(int index, int shift) {
*
* @return the encoded value to indicate if this encoder allows travel or not.
*/
public abstract long acceptWay(ReaderWay way);
public abstract EncodingManager.Access getAccess(ReaderWay way);

/**
* Analyze properties of a way and create the edge flags. This method is called in the second
* parsing step.
*/
public abstract IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way, long allowed, long relationFlags);
public abstract IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way, EncodingManager.Access access, long relationFlags);

/**
* Parse tags on nodes. Node tags can add to speed (like traffic_signals) where the value is
Expand Down Expand Up @@ -527,14 +519,6 @@ else if (maxTurnCosts == 1) {
return turnCostEncoder.setValue(0L, (int) costs);
}

protected boolean isFerry(long internalFlags) {
return (internalFlags & ferryBit) != 0;
}

protected boolean isAccept(long internalFlags) {
return (internalFlags & acceptBit) != 0;
}

public final DecimalEncodedValue getAverageSpeedEnc() {
if (speedEncoder == null)
throw new NullPointerException("FlagEncoder " + toString() + " not yet initialized");
Expand Down
Expand Up @@ -225,71 +225,71 @@ public int defineRelationBits(int index, int shift) {
}

@Override
public long acceptWay(ReaderWay way) {
public EncodingManager.Access getAccess(ReaderWay way) {
String highwayValue = way.getTag("highway");
if (highwayValue == null) {
long acceptPotentially = 0;
EncodingManager.Access accept = EncodingManager.Access.CAN_SKIP;

if (way.hasTag("route", ferries)) {
// if bike is NOT explicitly tagged allow bike but only if foot is not specified
String bikeTag = way.getTag("bicycle");
if (bikeTag == null && !way.hasTag("foot") || "yes".equals(bikeTag))
acceptPotentially = acceptBit | ferryBit;
accept = EncodingManager.Access.FERRY;
}

// special case not for all acceptedRailways, only platform
if (way.hasTag("railway", "platform"))
acceptPotentially = acceptBit;
accept = EncodingManager.Access.WAY;

if (way.hasTag("man_made", "pier"))
acceptPotentially = acceptBit;
accept = EncodingManager.Access.WAY;

if (acceptPotentially != 0) {
if (!accept.canSkip()) {
if (way.hasTag(restrictions, restrictedValues) && !getConditionalTagInspector().isRestrictedWayConditionallyPermitted(way))
return 0;
return acceptPotentially;
return EncodingManager.Access.CAN_SKIP;
return accept;
}

return 0;
return EncodingManager.Access.CAN_SKIP;
}

if (!highwaySpeeds.containsKey(highwayValue))
return 0;
return EncodingManager.Access.CAN_SKIP;

String sacScale = way.getTag("sac_scale");
if (sacScale != null) {
if ((way.hasTag("highway", "cycleway"))
&& (way.hasTag("sac_scale", "hiking")))
return acceptBit;
return EncodingManager.Access.WAY;
if (!isSacScaleAllowed(sacScale))
return 0;
return EncodingManager.Access.CAN_SKIP;
}

// use the way if it is tagged for bikes
if (way.hasTag("bicycle", intendedValues) ||
way.hasTag("bicycle", "dismount") ||
way.hasTag("highway", "cycleway"))
return acceptBit;
return EncodingManager.Access.WAY;

// accept only if explicitly tagged for bike usage
if ("motorway".equals(highwayValue) || "motorway_link".equals(highwayValue))
return 0;
return EncodingManager.Access.CAN_SKIP;

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

// do not use fords with normal bikes, flagged fords are in included above
if (isBlockFords() && (way.hasTag("highway", "ford") || way.hasTag("ford")))
return 0;
return EncodingManager.Access.CAN_SKIP;

// check access restrictions
if (way.hasTag(restrictions, restrictedValues) && !getConditionalTagInspector().isRestrictedWayConditionallyPermitted(way))
return 0;
return EncodingManager.Access.CAN_SKIP;

if (getConditionalTagInspector().isPermittedWayConditionallyRestricted(way))
return 0;
return EncodingManager.Access.CAN_SKIP;
else
return acceptBit;
return EncodingManager.Access.WAY;
}

boolean isSacScaleAllowed(String sacScale) {
Expand Down Expand Up @@ -339,12 +339,12 @@ protected double applyMaxSpeed(ReaderWay way, double speed) {
}

@Override
public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way, long allowed, long relationFlags) {
if (!isAccept(allowed))
public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way, EncodingManager.Access access, long relationFlags) {
if (access.canSkip())
return edgeFlags;

double wayTypeSpeed = getSpeed(way);
if (!isFerry(allowed)) {
if (!access.isFerry()) {
wayTypeSpeed = applyMaxSpeed(way, wayTypeSpeed);
handleSpeed(edgeFlags, way, wayTypeSpeed);
handleBikeRelated(edgeFlags, way, relationFlags > UNCHANGED.getValue());
Expand Down
Expand Up @@ -54,44 +54,44 @@ public int getVersion() {
}

@Override
public long acceptWay(ReaderWay way) {
public EncodingManager.Access getAccess(ReaderWay way) {
// TODO: Ferries have conditionals, like opening hours or are closed during some time in the year
String highwayValue = way.getTag("highway");
String firstValue = way.getFirstPriorityTag(restrictions);
if (highwayValue == null) {
if (way.hasTag("route", ferries)) {
if (restrictedValues.contains(firstValue))
return 0;
return EncodingManager.Access.CAN_SKIP;
if (intendedValues.contains(firstValue) ||
// implied default is allowed only if foot and bicycle is not specified:
firstValue.isEmpty() && !way.hasTag("foot") && !way.hasTag("bicycle"))
return acceptBit | ferryBit;
return EncodingManager.Access.FERRY;
}
return 0;
return EncodingManager.Access.CAN_SKIP;
}

if (!defaultSpeedMap.containsKey(highwayValue))
return 0;
return EncodingManager.Access.CAN_SKIP;

if (way.hasTag("impassable", "yes") || way.hasTag("status", "impassable"))
return 0;
return EncodingManager.Access.CAN_SKIP;

// multiple restrictions needs special handling compared to foot and bike, see also motorcycle
if (!firstValue.isEmpty()) {
if (restrictedValues.contains(firstValue) && !getConditionalTagInspector().isRestrictedWayConditionallyPermitted(way))
return 0;
return EncodingManager.Access.CAN_SKIP;
if (intendedValues.contains(firstValue))
return acceptBit;
return EncodingManager.Access.WAY;
}

// do not drive street cars into fords
if (isBlockFords() && ("ford".equals(highwayValue) || way.hasTag("ford")))
return 0;
return EncodingManager.Access.CAN_SKIP;

if (getConditionalTagInspector().isPermittedWayConditionallyRestricted(way))
return 0;
return EncodingManager.Access.CAN_SKIP;
else
return acceptBit;
return EncodingManager.Access.WAY;
}

@Override
Expand Down
30 changes: 15 additions & 15 deletions core/src/main/java/com/graphhopper/routing/util/CarFlagEncoder.java
Expand Up @@ -187,50 +187,50 @@ protected double getSpeed(ReaderWay way) {
}

@Override
public long acceptWay(ReaderWay way) {
public EncodingManager.Access getAccess(ReaderWay way) {
// TODO: Ferries have conditionals, like opening hours or are closed during some time in the year
String highwayValue = way.getTag("highway");
String firstValue = way.getFirstPriorityTag(restrictions);
if (highwayValue == null) {
if (way.hasTag("route", ferries)) {
if (restrictedValues.contains(firstValue))
return 0;
return EncodingManager.Access.CAN_SKIP;
if (intendedValues.contains(firstValue) ||
// implied default is allowed only if foot and bicycle is not specified:
firstValue.isEmpty() && !way.hasTag("foot") && !way.hasTag("bicycle"))
return acceptBit | ferryBit;
return EncodingManager.Access.FERRY;
}
return 0;
return EncodingManager.Access.CAN_SKIP;
}

if ("track".equals(highwayValue)) {
String tt = way.getTag("tracktype");
if (tt != null && !tt.equals("grade1") && !tt.equals("grade2") && !tt.equals("grade3"))
return 0;
return EncodingManager.Access.CAN_SKIP;
}

if (!defaultSpeedMap.containsKey(highwayValue))
return 0;
return EncodingManager.Access.CAN_SKIP;

if (way.hasTag("impassable", "yes") || way.hasTag("status", "impassable"))
return 0;
return EncodingManager.Access.CAN_SKIP;

// multiple restrictions needs special handling compared to foot and bike, see also motorcycle
if (!firstValue.isEmpty()) {
if (restrictedValues.contains(firstValue) && !getConditionalTagInspector().isRestrictedWayConditionallyPermitted(way))
return 0;
return EncodingManager.Access.CAN_SKIP;
if (intendedValues.contains(firstValue))
return acceptBit;
return EncodingManager.Access.WAY;
}

// do not drive street cars into fords
if (isBlockFords() && ("ford".equals(highwayValue) || way.hasTag("ford")))
return 0;
return EncodingManager.Access.CAN_SKIP;

if (getConditionalTagInspector().isPermittedWayConditionallyRestricted(way))
return 0;
return EncodingManager.Access.CAN_SKIP;
else
return acceptBit;
return EncodingManager.Access.WAY;
}

@Override
Expand All @@ -239,11 +239,11 @@ public long handleRelationTags(long oldRelationFlags, ReaderRelation relation) {
}

@Override
public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way, long allowed, long relationFlags) {
if (!isAccept(allowed))
public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way, EncodingManager.Access accept, long relationFlags) {
if (accept.canSkip())
return edgeFlags;

if (!isFerry(allowed)) {
if (!accept.isFerry()) {
// get assumed speed from highway type
double speed = getSpeed(way);
speed = applyMaxSpeed(way, speed);
Expand Down

0 comments on commit 2d93aa0

Please sign in to comment.