Skip to content

Commit bc573db

Browse files
karusselleasbar
andauthored
Include priority EncodedValue in CustomWeighting (graphhopper#2333)
* priority: use 4 bits and 0.1 factor * move 0.5 into EncodedValue * introduce priority in CustomWeighting * include priority and test bike fastest vs bike custom * rename enums to adapt to new range 0..15 * Add failing test * replace 1.5 with PriorityCode Co-authored-by: easbar <[email protected]>
1 parent eace9b0 commit bc573db

25 files changed

+332
-172
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
### 4.0 [not yet released]
22

3+
- renamed PriorityCode enums: AVOID_IF_POSSIBLE -> SLIGHT_AVOID, REACH_DEST -> AVOID, AVOID_AT_ALL_COSTS -> AVOID_MORE, WORST -> BAD
34
- added smoothness encoded value, used to determine bike speed (#2303)
45
- maps: custom_model is now included in URL (#2328)
56
- maps/isochrone: works for different profiles now (#2332)

core/src/main/java/com/graphhopper/routing/util/BikeCommonFlagEncoder.java

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ public void createEncodedValues(List<EncodedValue> registerNewEncodedValue, Stri
202202
// first two bits are reserved for route handling in superclass
203203
super.createEncodedValues(registerNewEncodedValue, prefix, index);
204204
registerNewEncodedValue.add(avgSpeedEnc = new UnsignedDecimalEncodedValue(getKey(prefix, "average_speed"), speedBits, speedFactor, speedTwoDirections));
205-
registerNewEncodedValue.add(priorityEnc = new UnsignedDecimalEncodedValue(getKey(prefix, "priority"), 3, PriorityCode.getFactor(1), false));
205+
registerNewEncodedValue.add(priorityEnc = new UnsignedDecimalEncodedValue(getKey(prefix, "priority"), 4, PriorityCode.getFactor(1), false));
206206

207207
bikeRouteEnc = getEnumEncodedValue(RouteNetwork.key("bike"), RouteNetwork.class);
208208
smoothnessEnc = getEnumEncodedValue(Smoothness.KEY, Smoothness.class);
@@ -313,20 +313,21 @@ public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way, EncodingManager.A
313313
wayTypeSpeed = applyMaxSpeed(way, wayTypeSpeed);
314314
Smoothness smoothness = smoothnessEnc.getEnum(false, edgeFlags);
315315
if (smoothness != Smoothness.MISSING) {
316-
// smoothness handling: Multiply speed with smoothnessFactor
317-
Double smoothnessSpeedFactor = smoothnessFactor.get(smoothness);
318-
wayTypeSpeed = (smoothnessSpeedFactor <= smoothnessFactorPushingSectionThreshold) ? PUSHING_SECTION_SPEED: (int)Math.round(smoothnessSpeedFactor * wayTypeSpeed);
316+
// smoothness handling: Multiply speed with smoothnessFactor
317+
double smoothnessSpeedFactor = smoothnessFactor.get(smoothness);
318+
wayTypeSpeed = (smoothnessSpeedFactor <= smoothnessFactorPushingSectionThreshold) ?
319+
PUSHING_SECTION_SPEED : Math.round(smoothnessSpeedFactor * wayTypeSpeed);
319320
}
320321
handleSpeed(edgeFlags, way, wayTypeSpeed);
321322
} else {
322323
double ferrySpeed = ferrySpeedCalc.getSpeed(way);
323324
handleSpeed(edgeFlags, way, ferrySpeed);
324325
accessEnc.setBool(false, edgeFlags, true);
325326
accessEnc.setBool(true, edgeFlags, true);
326-
priorityFromRelation = AVOID_IF_POSSIBLE.getValue();
327+
priorityFromRelation = SLIGHT_AVOID.getValue();
327328
}
328329

329-
priorityEnc.setDecimal(false, edgeFlags, PriorityCode.getFactor(handlePriority(way, wayTypeSpeed, priorityFromRelation)));
330+
priorityEnc.setDecimal(false, edgeFlags, PriorityCode.getValue(handlePriority(way, wayTypeSpeed, priorityFromRelation)));
330331
return edgeFlags;
331332
}
332333

@@ -430,11 +431,11 @@ private PriorityCode convertClassValueToPriority(String tagvalue) {
430431
case 0:
431432
return UNCHANGED;
432433
case -1:
433-
return AVOID_IF_POSSIBLE;
434+
return SLIGHT_AVOID;
434435
case -2:
435-
return REACH_DEST;
436+
return AVOID;
436437
case -3:
437-
return AVOID_AT_ALL_COSTS;
438+
return AVOID_MORE;
438439
default:
439440
return UNCHANGED;
440441
}
@@ -470,9 +471,9 @@ void collect(ReaderWay way, double wayTypeSpeed, TreeMap<Double, Integer> weight
470471
}
471472
} else if (avoidHighwayTags.contains(highway)
472473
|| isValidSpeed(maxSpeed) && maxSpeed >= avoidSpeedLimit && !"track".equals(highway)) {
473-
weightToPrioMap.put(50d, REACH_DEST.getValue());
474+
weightToPrioMap.put(50d, AVOID.getValue());
474475
if (way.hasTag("tunnel", intendedValues))
475-
weightToPrioMap.put(50d, AVOID_AT_ALL_COSTS.getValue());
476+
weightToPrioMap.put(50d, AVOID_MORE.getValue());
476477
}
477478

478479
String cycleway = way.getFirstPriorityTag(Arrays.asList("cycleway", "cycleway:left", "cycleway:right"));
@@ -484,7 +485,7 @@ void collect(ReaderWay way, double wayTypeSpeed, TreeMap<Double, Integer> weight
484485

485486
if (pushingSectionsHighways.contains(highway)
486487
|| "parking_aisle".equals(service)) {
487-
int pushingSectionPrio = AVOID_IF_POSSIBLE.getValue();
488+
int pushingSectionPrio = SLIGHT_AVOID.getValue();
488489
if (way.hasTag("bicycle", "use_sidepath")) {
489490
pushingSectionPrio = PREFER.getValue();
490491
}
@@ -493,15 +494,15 @@ void collect(ReaderWay way, double wayTypeSpeed, TreeMap<Double, Integer> weight
493494
if (way.hasTag("bicycle", "designated") || way.hasTag("bicycle", "official"))
494495
pushingSectionPrio = VERY_NICE.getValue();
495496
if (way.hasTag("foot", "yes")) {
496-
pushingSectionPrio = Math.max(pushingSectionPrio - 1, WORST.getValue());
497+
pushingSectionPrio = Math.max(pushingSectionPrio - 1, BAD.getValue());
497498
if (way.hasTag("segregated", "yes"))
498499
pushingSectionPrio = Math.min(pushingSectionPrio + 1, BEST.getValue());
499500
}
500501
weightToPrioMap.put(100d, pushingSectionPrio);
501502
}
502503

503504
if (way.hasTag("railway", "tram"))
504-
weightToPrioMap.put(50d, AVOID_AT_ALL_COSTS.getValue());
505+
weightToPrioMap.put(50d, AVOID_MORE.getValue());
505506

506507
String classBicycleValue = way.getTag(classBicycleKey);
507508
if (classBicycleValue != null) {

core/src/main/java/com/graphhopper/routing/util/FootFlagEncoder.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ public void createEncodedValues(List<EncodedValue> registerNewEncodedValue, Stri
154154
super.createEncodedValues(registerNewEncodedValue, prefix, index);
155155
// larger value required - ferries are faster than pedestrians
156156
registerNewEncodedValue.add(avgSpeedEnc = new UnsignedDecimalEncodedValue(getKey(prefix, "average_speed"), speedBits, speedFactor, speedTwoDirections));
157-
registerNewEncodedValue.add(priorityWayEncoder = new UnsignedDecimalEncodedValue(getKey(prefix, "priority"), 3, PriorityCode.getFactor(1), speedTwoDirections));
157+
registerNewEncodedValue.add(priorityWayEncoder = new UnsignedDecimalEncodedValue(getKey(prefix, "priority"), 4, PriorityCode.getFactor(1), speedTwoDirections));
158158

159159
footRouteEnc = getEnumEncodedValue(RouteNetwork.key("foot"), RouteNetwork.class);
160160
}
@@ -237,12 +237,12 @@ public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way, EncodingManager.A
237237
setSpeed(edgeFlags, true, true, way.hasTag("highway", "steps") ? MEAN_SPEED - 2 : MEAN_SPEED);
238238
}
239239
} else {
240-
priorityFromRelation = PriorityCode.AVOID_IF_POSSIBLE.getValue();
240+
priorityFromRelation = PriorityCode.SLIGHT_AVOID.getValue();
241241
double ferrySpeed = ferrySpeedCalc.getSpeed(way);
242242
setSpeed(edgeFlags, true, true, ferrySpeed);
243243
}
244244

245-
priorityWayEncoder.setDecimal(false, edgeFlags, PriorityCode.getFactor(handlePriority(way, priorityFromRelation)));
245+
priorityWayEncoder.setDecimal(false, edgeFlags, PriorityCode.getValue(handlePriority(way, priorityFromRelation)));
246246
return edgeFlags;
247247
}
248248

@@ -282,17 +282,17 @@ void collect(ReaderWay way, TreeMap<Double, Integer> weightToPrioMap) {
282282
weightToPrioMap.put(40d, PREFER.getValue());
283283
if (way.hasTag("tunnel", intendedValues)) {
284284
if (way.hasTag("sidewalk", sidewalksNoValues))
285-
weightToPrioMap.put(40d, AVOID_IF_POSSIBLE.getValue());
285+
weightToPrioMap.put(40d, SLIGHT_AVOID.getValue());
286286
else
287287
weightToPrioMap.put(40d, UNCHANGED.getValue());
288288
}
289289
} else if ((isValidSpeed(maxSpeed) && maxSpeed > 50) || avoidHighwayTags.contains(highway)) {
290290
if (!way.hasTag("sidewalk", sidewalkValues))
291-
weightToPrioMap.put(45d, AVOID_IF_POSSIBLE.getValue());
291+
weightToPrioMap.put(45d, SLIGHT_AVOID.getValue());
292292
}
293293

294294
if (way.hasTag("bicycle", "official") || way.hasTag("bicycle", "designated"))
295-
weightToPrioMap.put(44d, AVOID_IF_POSSIBLE.getValue());
295+
weightToPrioMap.put(44d, SLIGHT_AVOID.getValue());
296296
}
297297

298298
@Override

core/src/main/java/com/graphhopper/routing/util/HikeFlagEncoder.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,19 +77,19 @@ void collect(ReaderWay way, TreeMap<Double, Integer> weightToPrioMap) {
7777
weightToPrioMap.put(40d, PREFER.getValue());
7878
if (way.hasTag("tunnel", intendedValues)) {
7979
if (way.hasTag("sidewalk", sidewalksNoValues))
80-
weightToPrioMap.put(40d, REACH_DEST.getValue());
80+
weightToPrioMap.put(40d, AVOID.getValue());
8181
else
8282
weightToPrioMap.put(40d, UNCHANGED.getValue());
8383
}
8484
} else if ((isValidSpeed(maxSpeed) && maxSpeed > 50) || avoidHighwayTags.contains(highway)) {
8585
if (way.hasTag("sidewalk", sidewalksNoValues))
86-
weightToPrioMap.put(45d, WORST.getValue());
86+
weightToPrioMap.put(45d, BAD.getValue());
8787
else
88-
weightToPrioMap.put(45d, REACH_DEST.getValue());
88+
weightToPrioMap.put(45d, AVOID.getValue());
8989
}
9090

9191
if (way.hasTag("bicycle", "official") || way.hasTag("bicycle", "designated"))
92-
weightToPrioMap.put(44d, AVOID_IF_POSSIBLE.getValue());
92+
weightToPrioMap.put(44d, SLIGHT_AVOID.getValue());
9393
}
9494

9595

core/src/main/java/com/graphhopper/routing/util/MotorcycleFlagEncoder.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import com.graphhopper.reader.ReaderWay;
2121
import com.graphhopper.routing.ev.DecimalEncodedValue;
2222
import com.graphhopper.routing.ev.EncodedValue;
23-
import com.graphhopper.routing.ev.MaxSpeed;
2423
import com.graphhopper.routing.ev.UnsignedDecimalEncodedValue;
2524
import com.graphhopper.routing.util.parsers.helpers.OSMValueExtractor;
2625
import com.graphhopper.routing.weighting.CurvatureWeighting;
@@ -117,7 +116,7 @@ public void createEncodedValues(List<EncodedValue> registerNewEncodedValue, Stri
117116
// first two bits are reserved for route handling in superclass
118117
super.createEncodedValues(registerNewEncodedValue, prefix, index);
119118

120-
registerNewEncodedValue.add(priorityWayEncoder = new UnsignedDecimalEncodedValue(getKey(prefix, "priority"), 3, PriorityCode.getFactor(1), false));
119+
registerNewEncodedValue.add(priorityWayEncoder = new UnsignedDecimalEncodedValue(getKey(prefix, "priority"), 4, PriorityCode.getFactor(1), false));
121120
registerNewEncodedValue.add(curvatureEncoder = new UnsignedDecimalEncodedValue(getKey(prefix, "curvature"), 4, 0.1, false));
122121
}
123122

@@ -208,17 +207,15 @@ public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way, EncodingManager.A
208207
setSpeed(true, edgeFlags, ferrySpeed);
209208
}
210209

211-
priorityWayEncoder.setDecimal(false, edgeFlags, PriorityCode.getFactor(handlePriority(way)));
212-
213-
// Set the curvature to the Maximum
214-
curvatureEncoder.setDecimal(false, edgeFlags, PriorityCode.getFactor(10));
210+
priorityWayEncoder.setDecimal(false, edgeFlags, PriorityCode.getValue(handlePriority(way)));
211+
curvatureEncoder.setDecimal(false, edgeFlags, 10.0 / 7.0);
215212
return edgeFlags;
216213
}
217214

218215
private int handlePriority(ReaderWay way) {
219216
String highway = way.getTag("highway", "");
220217
if (avoidSet.contains(highway)) {
221-
return PriorityCode.WORST.getValue();
218+
return PriorityCode.BAD.getValue();
222219
} else if (preferSet.contains(highway)) {
223220
return PriorityCode.BEST.getValue();
224221
}

core/src/main/java/com/graphhopper/routing/util/PriorityCode.java

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,18 @@
2424
* @author Peter Karich
2525
*/
2626
public enum PriorityCode {
27-
WORST(0),
28-
AVOID_AT_ALL_COSTS(1),
29-
REACH_DEST(2),
30-
AVOID_IF_POSSIBLE(3),
31-
UNCHANGED(4),
32-
PREFER(5),
33-
VERY_NICE(6),
34-
BEST(7);
27+
EXCLUDE(0),
28+
REACH_DESTINATION(1),
29+
VERY_BAD(3),
30+
BAD(5),
31+
AVOID_MORE(6),
32+
AVOID(8),
33+
SLIGHT_AVOID(9),
34+
UNCHANGED(10),
35+
SLIGHT_PREFER(11),
36+
PREFER(12),
37+
VERY_NICE(13),
38+
BEST(15);
3539
private final int value;
3640

3741
PriorityCode(int value) {
@@ -42,11 +46,11 @@ public int getValue() {
4246
return value;
4347
}
4448

45-
/**
46-
* This method returns the PriorityCode.value in a range between 0 and 1 suitable for direct usage in a Weighting.
47-
*/
48-
public static double getFactor(int val) {
49-
return (double) val / BEST.getValue();
49+
public static double getFactor(int value) {
50+
return (double) value / 10.0;
5051
}
5152

53+
public static double getValue(int value) {
54+
return getFactor(value);
55+
}
5256
}

core/src/main/java/com/graphhopper/routing/util/RacingBikeFlagEncoder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ void collect(ReaderWay way, double wayTypeSpeed, TreeMap<Double, Integer> weight
145145
if ("grade1".equals(trackType))
146146
weightToPrioMap.put(110d, PREFER.getValue());
147147
else if (trackType == null || trackType.startsWith("grade"))
148-
weightToPrioMap.put(110d, AVOID_AT_ALL_COSTS.getValue());
148+
weightToPrioMap.put(110d, AVOID_MORE.getValue());
149149
}
150150
}
151151

core/src/main/java/com/graphhopper/routing/util/WheelchairFlagEncoder.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
import java.util.Set;
2929
import java.util.TreeMap;
3030

31-
import static com.graphhopper.routing.util.PriorityCode.REACH_DEST;
31+
import static com.graphhopper.routing.util.PriorityCode.AVOID;
3232
import static com.graphhopper.routing.util.PriorityCode.VERY_NICE;
3333

3434
/**
@@ -272,7 +272,7 @@ protected int handlePriority(ReaderWay way, Integer priorityFromRelation) {
272272
if (way.hasTag("wheelchair", "designated")) {
273273
weightToPrioMap.put(102d, VERY_NICE.getValue());
274274
} else if (way.hasTag("wheelchair", "limited")) {
275-
weightToPrioMap.put(102d, REACH_DEST.getValue());
275+
weightToPrioMap.put(102d, AVOID.getValue());
276276
}
277277

278278
return weightToPrioMap.lastEntry().getValue();

core/src/main/java/com/graphhopper/routing/weighting/CurvatureWeighting.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@
2020
import com.graphhopper.routing.ev.DecimalEncodedValue;
2121
import com.graphhopper.routing.util.EncodingManager;
2222
import com.graphhopper.routing.util.FlagEncoder;
23+
import com.graphhopper.routing.util.PriorityCode;
2324
import com.graphhopper.util.EdgeIteratorState;
2425
import com.graphhopper.util.PMap;
2526

27+
import static com.graphhopper.routing.util.PriorityCode.BEST;
2628
import static com.graphhopper.routing.weighting.TurnCostProvider.NO_TURN_COST_PROVIDER;
2729

2830
/**
@@ -45,8 +47,7 @@ public CurvatureWeighting(FlagEncoder flagEncoder, PMap pMap, TurnCostProvider t
4547
curvatureEnc = flagEncoder.getDecimalEncodedValue(EncodingManager.getKey(flagEncoder, "curvature"));
4648
avSpeedEnc = flagEncoder.getDecimalEncodedValue(EncodingManager.getKey(flagEncoder, "average_speed"));
4749
double minBendiness = 1; // see correctErrors
48-
double maxPriority = 1; // BEST / BEST
49-
minFactor = minBendiness / Math.log(flagEncoder.getMaxSpeed()) / (0.5 + maxPriority);
50+
minFactor = minBendiness / Math.log(flagEncoder.getMaxSpeed()) / PriorityCode.getValue(BEST.getValue());
5051
}
5152

5253
@Override
@@ -63,8 +64,7 @@ public double calcEdgeWeight(EdgeIteratorState edgeState, boolean reverse) {
6364

6465
// We use the log of the speed to decrease the impact of the speed, therefore we don't use the highway
6566
double regularWeight = roadDistance / Math.log(speed);
66-
67-
return (bendiness * regularWeight) / (0.5 + priority);
67+
return (bendiness * regularWeight) / priority;
6868
}
6969

7070
protected double getRoadSpeed(EdgeIteratorState edge, boolean reverse) {

core/src/main/java/com/graphhopper/routing/weighting/PriorityWeighting.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,14 @@
3434
public class PriorityWeighting extends FastestWeighting {
3535

3636
private final double minFactor;
37+
private final double maxPrio;
3738
private final DecimalEncodedValue priorityEnc;
3839

3940
public PriorityWeighting(FlagEncoder encoder, PMap pMap, TurnCostProvider turnCostProvider) {
4041
super(encoder, pMap, turnCostProvider);
4142
priorityEnc = encoder.getDecimalEncodedValue(EncodingManager.getKey(encoder, "priority"));
42-
double maxPriority = PriorityCode.getFactor(BEST.getValue());
43-
minFactor = 1 / (0.5 + maxPriority);
43+
minFactor = 1 / PriorityCode.getValue(BEST.getValue());
44+
maxPrio = PriorityCode.getFactor(BEST.getValue());
4445
}
4546

4647
@Override
@@ -53,6 +54,9 @@ public double calcEdgeWeight(EdgeIteratorState edgeState, boolean reverse) {
5354
double weight = super.calcEdgeWeight(edgeState, reverse);
5455
if (Double.isInfinite(weight))
5556
return Double.POSITIVE_INFINITY;
56-
return weight / (0.5 + edgeState.get(priorityEnc));
57+
double priority = edgeState.get(priorityEnc);
58+
if (priority > maxPrio)
59+
throw new IllegalArgumentException("priority cannot be bigger than " + maxPrio + " but was " + priority);
60+
return weight / priority;
5761
}
5862
}

0 commit comments

Comments
 (0)