@@ -44,6 +44,7 @@ public class InstructionsFromEdges implements Path.EdgeVisitor {
44
44
private final BooleanEncodedValue roundaboutEnc ;
45
45
private final BooleanEncodedValue roadClassLinkEnc ;
46
46
private final EnumEncodedValue <RoadClass > roadClassEnc ;
47
+ private final EnumEncodedValue <RoadEnvironment > roadEnvEnc ;
47
48
private final IntEncodedValue lanesEnc ;
48
49
private final DecimalEncodedValue maxSpeedEnc ;
49
50
@@ -78,6 +79,7 @@ public class InstructionsFromEdges implements Path.EdgeVisitor {
78
79
private boolean prevInRoundabout ;
79
80
private String prevDestinationAndRef ;
80
81
private String prevName ;
82
+ private RoadEnvironment prevRoadEnv ;
81
83
private String prevInstructionName ;
82
84
83
85
private static final int MAX_U_TURN_DISTANCE = 35 ;
@@ -86,6 +88,7 @@ public InstructionsFromEdges(Graph graph, Weighting weighting, EncodedValueLooku
86
88
InstructionList ways ) {
87
89
this .weighting = weighting ;
88
90
this .roundaboutEnc = evLookup .getBooleanEncodedValue (Roundabout .KEY );
91
+ this .roadEnvEnc = evLookup .getEnumEncodedValue (RoadEnvironment .KEY , RoadEnvironment .class );
89
92
this .roadClassEnc = evLookup .getEnumEncodedValue (RoadClass .KEY , RoadClass .class );
90
93
this .roadClassLinkEnc = evLookup .getBooleanEncodedValue (RoadClassLink .KEY );
91
94
this .maxSpeedEnc = evLookup .getDecimalEncodedValue (MaxSpeed .KEY );
@@ -95,6 +98,7 @@ public InstructionsFromEdges(Graph graph, Weighting weighting, EncodedValueLooku
95
98
prevNode = -1 ;
96
99
prevInRoundabout = false ;
97
100
prevName = null ;
101
+ prevRoadEnv = null ;
98
102
99
103
BooleanEncodedValue carAccessEnc = evLookup .getBooleanEncodedValue (VehicleAccess .key ("car" ));
100
104
outEdgeExplorer = graph .createEdgeExplorer (edge -> edge .get (carAccessEnc ));
@@ -149,6 +153,8 @@ public void next(EdgeIteratorState edge, int index, int prevEdgeId) {
149
153
final String destination = (String ) edge .getValue (STREET_DESTINATION ); // getValue is fast if it does not exist in edge
150
154
final String destinationRef = (String ) edge .getValue (STREET_DESTINATION_REF );
151
155
final String motorwayJunction = (String ) edge .getValue (MOTORWAY_JUNCTION );
156
+ final RoadEnvironment roadEnv = edge .get (roadEnvEnc );
157
+
152
158
if ((prevInstruction == null ) && (!isRoundabout )) // very first instruction (if not in Roundabout)
153
159
{
154
160
int sign = Instruction .CONTINUE_ON_STREET ;
@@ -157,12 +163,15 @@ public void next(EdgeIteratorState edge, int index, int prevEdgeId) {
157
163
prevInstruction .setExtraInfo (STREET_DESTINATION , destination );
158
164
prevInstruction .setExtraInfo (STREET_DESTINATION_REF , destinationRef );
159
165
prevInstruction .setExtraInfo (MOTORWAY_JUNCTION , motorwayJunction );
166
+ prevInstruction .setExtraInfo ("ferry" , InstructionsHelper .createFerryInfo (roadEnv , prevRoadEnv ));
167
+
160
168
double startLat = nodeAccess .getLat (baseNode );
161
169
double startLon = nodeAccess .getLon (baseNode );
162
170
double heading = AngleCalc .ANGLE_CALC .calcAzimuth (startLat , startLon , latitude , longitude );
163
171
prevInstruction .setExtraInfo ("heading" , Helper .round (heading , 2 ));
164
172
ways .add (prevInstruction );
165
173
prevName = name ;
174
+ prevRoadEnv = roadEnv ;
166
175
prevDestinationAndRef = destination + destinationRef ;
167
176
168
177
} else if (isRoundabout ) {
@@ -197,6 +206,7 @@ public void next(EdgeIteratorState edge, int index, int prevEdgeId) {
197
206
{
198
207
prevOrientation = AngleCalc .ANGLE_CALC .calcOrientation (prevLat , prevLon , latitude , longitude );
199
208
prevName = name ;
209
+ prevRoadEnv = roadEnv ;
200
210
prevDestinationAndRef = destination + destinationRef ;
201
211
}
202
212
prevInstruction = roundaboutInstruction ;
@@ -220,6 +230,7 @@ public void next(EdgeIteratorState edge, int index, int prevEdgeId) {
220
230
prevInstruction .setExtraInfo (STREET_DESTINATION , destination );
221
231
prevInstruction .setExtraInfo (STREET_DESTINATION_REF , destinationRef );
222
232
prevInstruction .setExtraInfo (MOTORWAY_JUNCTION , motorwayJunction );
233
+ prevInstruction .setExtraInfo ("ferry" , InstructionsHelper .createFerryInfo (roadEnv , prevRoadEnv ));
223
234
224
235
// calc angle between roundabout entrance and exit
225
236
double orientation = AngleCalc .ANGLE_CALC .calcOrientation (prevLat , prevLon , latitude , longitude );
@@ -239,6 +250,7 @@ public void next(EdgeIteratorState edge, int index, int prevEdgeId) {
239
250
240
251
prevInstructionName = prevName ;
241
252
prevName = name ;
253
+ prevRoadEnv = roadEnv ;
242
254
prevDestinationAndRef = destination + destinationRef ;
243
255
244
256
} else {
@@ -296,10 +308,12 @@ public void next(EdgeIteratorState edge, int index, int prevEdgeId) {
296
308
prevInstruction .setExtraInfo (STREET_DESTINATION , destination );
297
309
prevInstruction .setExtraInfo (STREET_DESTINATION_REF , destinationRef );
298
310
prevInstruction .setExtraInfo (MOTORWAY_JUNCTION , motorwayJunction );
311
+ prevInstruction .setExtraInfo ("ferry" , InstructionsHelper .createFerryInfo (roadEnv , prevRoadEnv ));
299
312
}
300
313
// Update the prevName, since we don't always create an instruction on name changes the previous
301
314
// name can be an old name. This leads to incorrect turn instructions due to name changes
302
315
prevName = name ;
316
+ prevRoadEnv = roadEnv ;
303
317
prevDestinationAndRef = destination + destinationRef ;
304
318
}
305
319
@@ -351,10 +365,13 @@ private int getTurn(EdgeIteratorState edge, int baseNode, int prevNode, int adjN
351
365
InstructionsOutgoingEdges outgoingEdges = new InstructionsOutgoingEdges (prevEdge , edge , weighting , maxSpeedEnc ,
352
366
roadClassEnc , roadClassLinkEnc , lanesEnc , allExplorer , nodeAccess , prevNode , baseNode , adjNode );
353
367
int nrOfPossibleTurns = outgoingEdges .getAllowedTurns ();
368
+ RoadEnvironment roadEnv = edge .get (roadEnvEnc );
354
369
355
370
// there is no other turn possible
356
371
if (nrOfPossibleTurns <= 1 ) {
357
- if (Math .abs (sign ) > 1 && outgoingEdges .getVisibleTurns () > 1 && !outgoingEdges .mergedOrSplitWay ()) {
372
+ if (InstructionsHelper .isToFerry (roadEnv , prevRoadEnv )) return Instruction .FERRY ;
373
+ if (Math .abs (sign ) > 1 && outgoingEdges .getVisibleTurns () > 1 && !outgoingEdges .mergedOrSplitWay ()
374
+ || InstructionsHelper .isFromFerry (roadEnv , prevRoadEnv )) {
358
375
// This is an actual turn because |sign| > 1
359
376
// There could be some confusion, if we would not create a turn instruction, even though it is the only
360
377
// possible turn, also see #1048
@@ -366,9 +383,11 @@ private int getTurn(EdgeIteratorState edge, int baseNode, int prevNode, int adjN
366
383
367
384
// Very certain, this is a turn
368
385
if (Math .abs (sign ) > 1 ) {
386
+ if (InstructionsHelper .isToFerry (roadEnv , prevRoadEnv )) return Instruction .FERRY ;
369
387
// Don't show an instruction if the user is following a street, even though the street is
370
388
// bending. We should only do this, if following the street is the obvious choice.
371
389
if (InstructionsHelper .isSameName (name , prevName ) && outgoingEdges .outgoingEdgesAreSlowerByFactor (2 )
390
+ || InstructionsHelper .isFromFerry (roadEnv , prevRoadEnv )
372
391
|| outgoingEdges .mergedOrSplitWay ()) {
373
392
return Instruction .IGNORE ;
374
393
}
@@ -397,6 +416,11 @@ private int getTurn(EdgeIteratorState edge, int baseNode, int prevNode, int adjN
397
416
// Signs provide too less detail, so we use the delta for a precise comparison
398
417
double delta = InstructionsHelper .calculateOrientationDelta (prevLat , prevLon , lat , lon , prevOrientation );
399
418
419
+ if (InstructionsHelper .isToFerry (roadEnv , prevRoadEnv ))
420
+ return Instruction .FERRY ;
421
+ else if (InstructionsHelper .isFromFerry (roadEnv , prevRoadEnv ))
422
+ return Instruction .CONTINUE_ON_STREET ;
423
+
400
424
// This state is bad! Two streets are going more or less straight
401
425
// Happens a lot for trunk_links
402
426
// For _links, comparing flags works quite good, as links usually have different speeds => different flags
0 commit comments