improve collapse-handling
This commit is contained in:
		
							parent
							
								
									dfafe7dc5f
								
							
						
					
					
						commit
						1dfdb38d4a
					
				| @ -3,6 +3,7 @@ | |||||||
| 
 | 
 | ||||||
|    - Guidance: |    - Guidance: | ||||||
|      - improved handling of sliproads (emit turns instead of 'take the ramp') |      - improved handling of sliproads (emit turns instead of 'take the ramp') | ||||||
|  |      - improved collapsing of instructions. Some 'new name' instructions will be suppressed if they are without alternative and the segment is short | ||||||
|      - BREAKING: modifies the file format with new internal identifiers |      - BREAKING: modifies the file format with new internal identifiers | ||||||
| 
 | 
 | ||||||
|    - API: |    - API: | ||||||
|  | |||||||
| @ -115,7 +115,7 @@ Feature: Bike - Oneway streets | |||||||
| 
 | 
 | ||||||
|     Scenario: Bike - Two consecutive oneways |     Scenario: Bike - Two consecutive oneways | ||||||
|         Given the node map |         Given the node map | ||||||
|             | a | b | c | |             | a | b |   | c | | ||||||
| 
 | 
 | ||||||
|         And the ways |         And the ways | ||||||
|             | nodes | oneway | |             | nodes | oneway | | ||||||
|  | |||||||
| @ -68,7 +68,7 @@ Feature: Car - Oneway streets | |||||||
| 
 | 
 | ||||||
|     Scenario: Car - Two consecutive oneways |     Scenario: Car - Two consecutive oneways | ||||||
|         Given the node map |         Given the node map | ||||||
|             | a | b | c | |             | a | b |   | c | | ||||||
| 
 | 
 | ||||||
|         And the ways |         And the ways | ||||||
|             | nodes | oneway | |             | nodes | oneway | | ||||||
|  | |||||||
| @ -5,6 +5,7 @@ Feature: Car - Turn restrictions | |||||||
| 
 | 
 | ||||||
|     Background: Use car routing |     Background: Use car routing | ||||||
|         Given the profile "car" |         Given the profile "car" | ||||||
|  |         Given a grid size of 200 meters | ||||||
| 
 | 
 | ||||||
|     @no_turning |     @no_turning | ||||||
|     Scenario: Car - No left turn |     Scenario: Car - No left turn | ||||||
|  | |||||||
| @ -12,19 +12,17 @@ Feature: Traffic - turn penalties | |||||||
|             | nodes | highway | |             | nodes | highway | | ||||||
|             | ad    | primary | |             | ad    | primary | | ||||||
|             | cd    | primary | |             | cd    | primary | | ||||||
|             | de    | primary | |             | def   | primary | | ||||||
|             | dhk   | primary | |             | dhk   | primary | | ||||||
| 
 | 
 | ||||||
|             | bf    | primary | |             | bf    | primary | | ||||||
|             | ef    | primary | |  | ||||||
|             | fg    | primary | |             | fg    | primary | | ||||||
|             | fim   | primary | |             | fim   | primary | | ||||||
| 
 | 
 | ||||||
|             | jk    | primary | |             | jk    | primary | | ||||||
|             | kl    | primary | |             | klm   | primary | | ||||||
|             | ko    | primary | |             | ko    | primary | | ||||||
| 
 | 
 | ||||||
|             | lm    | primary | |  | ||||||
|             | mn    | primary | |             | mn    | primary | | ||||||
|             | mp    | primary | |             | mp    | primary | | ||||||
|         And the profile "car" |         And the profile "car" | ||||||
| @ -37,15 +35,15 @@ Feature: Traffic - turn penalties | |||||||
|                                                                   # straight |                                                                   # straight | ||||||
|             | i    | g  | fim,fg,fg       | 59 km/h | 12s  +-1  | |             | i    | g  | fim,fg,fg       | 59 km/h | 12s  +-1  | | ||||||
|                                                                   # right |                                                                   # right | ||||||
|             | a    | e  | ad,de,de       | 57 km/h | 12.5s +-1 | |             | a    | e  | ad,def,def      | 57 km/h | 12.5s +-1 | | ||||||
|                                                                   # left |                                                                   # left | ||||||
|             | c    | g  | cd,de,ef,fg,fg | 63 km/h | 23s +-1   | |             | c    | g  | cd,def,fg,fg    | 63 km/h | 23s +-1   | | ||||||
|                                                                   # double straight |                                                                   # double straight | ||||||
|             | p    | g  | mp,fim,fg,fg    | 61 km/h | 23.5s +-1 | |             | p    | g  | mp,fim,fg,fg    | 61 km/h | 23.5s +-1 | | ||||||
|                                                                   # straight-right |                                                                   # straight-right | ||||||
|             | a    | l  | ad,dhk,kl,kl   | 60 km/h | 24s +-1   | |             | a    | l  | ad,dhk,klm,klm  | 60 km/h | 24s +-1   | | ||||||
|                                                                   # straight-left |                                                                   # straight-left | ||||||
|             | l    | e  | kl,dhk,de,de   | 59 km/h | 24.5s +-1 | |             | l    | e  | klm,dhk,def,def | 59 km/h | 24.5s +-1 | | ||||||
|                                                                   # double right |                                                                   # double right | ||||||
|             | g    | n  | fg,fim,mn,mn    | 57 km/h | 25s +-1   | |             | g    | n  | fg,fim,mn,mn    | 57 km/h | 25s +-1   | | ||||||
|                                                                   # double left |                                                                   # double left | ||||||
| @ -67,19 +65,19 @@ Feature: Traffic - turn penalties | |||||||
|                                                                               # straight |                                                                               # straight | ||||||
|             | i    | g  | fim,fg,fg             | 55 km/h | 13s +-1   | |             | i    | g  | fim,fg,fg             | 55 km/h | 13s +-1   | | ||||||
|                                                                               # right - ifg penalty |                                                                               # right - ifg penalty | ||||||
|             | a    | e  | ad,de,de                 | 64 km/h | 11s +-1   | |             | a    | e  | ad,def,def            | 64 km/h | 11s +-1   | | ||||||
|                                                                               # left - faster because of negative ade penalty |                                                                               # left - faster because of negative ade penalty | ||||||
|             | c    | g  | cd,de,ef,fg,fg           | 63 km/h | 23s +-1   | |             | c    | g  | cd,def,fg,fg          | 63 km/h | 23s +-1   | | ||||||
|                                                                               # double straight |                                                                               # double straight | ||||||
|             | p    | g  | mp,fim,fg,fg          | 59 km/h | 24.5s +-1 | |             | p    | g  | mp,fim,fg,fg          | 59 km/h | 24.5s +-1 | | ||||||
|                                                                               # straight-right - ifg penalty |                                                                               # straight-right - ifg penalty | ||||||
|             | a    | l  | ad,de,ef,fim,lm,lm       | 61 km/h | 35.5s +-1 | |             | a    | l  | ad,def,fim,klm,klm    | 61 km/h | 35.5s +-1 | | ||||||
|                                                                               # was straight-left - forced around by hkl penalty |                                                                               # was straight-left - forced around by hkl penalty | ||||||
|             | l    | e  | lm,fim,ef,ef             | 57 km/h | 25s +-1   | |             | l    | e  | klm,fim,def,def       | 57 km/h | 25s +-1   | | ||||||
|                                                                               # double right - forced left by lkh penalty |                                                                               # double right - forced left by lkh penalty | ||||||
|             | g    | n  | fg,fim,mn,mn          | 30 km/h | 47.5s +-1 | |             | g    | n  | fg,fim,mn,mn          | 30 km/h | 47.5s +-1 | | ||||||
|                                                                               # double left - imn penalty |                                                                               # double left - imn penalty | ||||||
|             | j    | c  | jk,kl,lm,fim,ef,de,cd,cd | 60 km/h | 48s +-1   | |             | j    | c  | jk,klm,fim,def,cd,cd  | 60 km/h | 48s +-1   | | ||||||
|                                                                               # double left - hdc penalty ever so slightly higher than imn; forces all the way around |                                                                               # double left - hdc penalty ever so slightly higher than imn; forces all the way around | ||||||
| 
 | 
 | ||||||
|     Scenario: Too-negative penalty clamps, but does not fail |     Scenario: Too-negative penalty clamps, but does not fail | ||||||
| @ -92,6 +90,6 @@ Feature: Traffic - turn penalties | |||||||
|         When I route I should get |         When I route I should get | ||||||
|             | from | to | route      | time    | |             | from | to | route      | time    | | ||||||
|             | a    | d  | ad,ad      | 10s +-1 | |             | a    | d  | ad,ad      | 10s +-1 | | ||||||
|             | a    | e  | ad,de,de | 10s +-1 | |             | a    | e  | ad,def,def | 10s +-1 | | ||||||
|             | b    | f  | bf,bf      | 10s +-1 | |             | b    | f  | bf,bf      | 10s +-1 | | ||||||
|             | b    | g  | bf,fg,fg   | 20s +-1 | |             | b    | g  | bf,fg,fg   | 20s +-1 | | ||||||
|  | |||||||
| @ -345,3 +345,143 @@ Feature: Collapse | |||||||
|             | a,d       | first,first,first,first | depart,continue left,continue right,arrive | |             | a,d       | first,first,first,first | depart,continue left,continue right,arrive | | ||||||
|             | a,e       | first,second,second     | depart,turn left,arrive                    | |             | a,e       | first,second,second     | depart,turn left,arrive                    | | ||||||
|             | a,f       | first,third,third       | depart,turn straight,arrive                | |             | a,f       | first,third,third       | depart,turn straight,arrive                | | ||||||
|  | 
 | ||||||
|  |      Scenario: Bridge on unnamed road | ||||||
|  |         Given the node map | ||||||
|  |             | a | b |   |   |   | c | d | | ||||||
|  | 
 | ||||||
|  |         And the ways | ||||||
|  |             | nodes | highway | name   | | ||||||
|  |             | ab    | primary |        | | ||||||
|  |             | bc    | primary | Bridge | | ||||||
|  |             | cd    | primary |        | | ||||||
|  | 
 | ||||||
|  |         When I route I should get | ||||||
|  |             | waypoints | route | turns         | | ||||||
|  |             | a,d       | ,     | depart,arrive | | ||||||
|  | 
 | ||||||
|  |      Scenario: Crossing Bridge into Segregated Turn | ||||||
|  |         Given the node map | ||||||
|  |             |   |   |   |   |   | f | | ||||||
|  |             | i | h |   |   | g | e | | ||||||
|  |             | a | b |   |   | c | d | | ||||||
|  | 
 | ||||||
|  |         And the ways | ||||||
|  |             | nodes | highway | oneway | name        | | ||||||
|  |             | ab    | primary | yes    | to_bridge   | | ||||||
|  |             | bc    | primary | yes    | bridge      | | ||||||
|  |             | cd    | primary | yes    | off_bridge  | | ||||||
|  |             | de    | primary | yes    |             | | ||||||
|  |             | ef    | primary | no     | target_road | | ||||||
|  |             | eg    | primary | yes    | off_bridge  | | ||||||
|  |             | gh    | primary | yes    | bridge      | | ||||||
|  |             | hi    | primary | yes    | to_bridge   | | ||||||
|  | 
 | ||||||
|  |         When I route I should get | ||||||
|  |             | waypoints | route                             | turns                   | | ||||||
|  |             | a,f       | to_bridge,target_road,target_road | depart,turn left,arrive | | ||||||
|  | 
 | ||||||
|  |     Scenario: Pankenbruecke | ||||||
|  |         Given the node map | ||||||
|  |             | h |   |   |   |   |   | i |   |   |   |   |   |   | | ||||||
|  |             |   |   | b | c | d | e | f |   |   |   |   |   | g | | ||||||
|  |             | a |   |   |   |   |   |   |   |   |   |   |   |   | | ||||||
|  | 
 | ||||||
|  |         And the ways | ||||||
|  |             | nodes | highway | name    | oneway | | ||||||
|  |             | abh   | primary | inroad  | yes    | | ||||||
|  |             | bc    | primary | inroad  | no     | | ||||||
|  |             | cd    | primary | bridge  | no     | | ||||||
|  |             | defg  | primary | outroad | no     | | ||||||
|  |             | fi    | primary | cross   | no     | | ||||||
|  | 
 | ||||||
|  |        When I route I should get | ||||||
|  |             | waypoints | route                  | turns                           | | ||||||
|  |             | a,g       | inroad,outroad,outroad | depart,new name straight,arrive | | ||||||
|  |             | a,i       | inroad,cross,cross     | depart,turn left,arrive         | | ||||||
|  | 
 | ||||||
|  |      Scenario: Close Turns - Don't Collapse | ||||||
|  |         Given the node map | ||||||
|  |             |   | g | d |   | | ||||||
|  |             |   |   |   |   | | ||||||
|  |             | e | b | c | f | | ||||||
|  |             |   |   |   |   | | ||||||
|  |             |   | a | h |   | | ||||||
|  | 
 | ||||||
|  |         And the ways | ||||||
|  |             | nodes | highway | name     | | ||||||
|  |             | ab    | primary | in       | | ||||||
|  |             | ebcf  | primary | cross    | | ||||||
|  |             | cd    | primary | out      | | ||||||
|  |             | bg    | primary | straight | | ||||||
|  |             | ch    | primary | reverse  | | ||||||
|  | 
 | ||||||
|  |         When I route I should get | ||||||
|  |             | waypoints | route                    | turns                               | | ||||||
|  |             | a,d       | in,cross,out,out         | depart,turn right,turn left,arrive  | | ||||||
|  |             | a,h       | in,cross,reverse,reverse | depart,turn right,turn right,arrive | | ||||||
|  |             | g,d       | straight,cross,out,out   | depart,turn left,turn left,arrive   | | ||||||
|  | 
 | ||||||
|  |      Scenario: No Name During Turns | ||||||
|  |         Given the node map | ||||||
|  |             | a | b |   | | ||||||
|  |             |   | c | d | | ||||||
|  | 
 | ||||||
|  |         And the ways | ||||||
|  |             | nodes | highway  | name | | ||||||
|  |             | ab    | tertiary | road | | ||||||
|  |             | bc    | tertiary |      | | ||||||
|  |             | cd    | tertiary | road | | ||||||
|  | 
 | ||||||
|  |         When I route I should get | ||||||
|  |             | waypoints | route     | turns         | | ||||||
|  |             | a,d       | road,road | depart,arrive | | ||||||
|  | 
 | ||||||
|  |     Scenario: No Name During Turns, Random Oneway | ||||||
|  |         Given the node map | ||||||
|  |             | a | b |   | | ||||||
|  |             |   | c | d | | ||||||
|  | 
 | ||||||
|  |         And the ways | ||||||
|  |             | nodes | highway  | name | oneway | | ||||||
|  |             | ab    | tertiary | road | no     | | ||||||
|  |             | bc    | tertiary |      | yes    | | ||||||
|  |             | cd    | tertiary | road | no     | | ||||||
|  | 
 | ||||||
|  |         When I route I should get | ||||||
|  |             | waypoints | route     | turns         | | ||||||
|  |             | a,d       | road,road | depart,arrive | | ||||||
|  | 
 | ||||||
|  |     Scenario: Pulled Back Turn | ||||||
|  |         Given the node map | ||||||
|  |             |   |   | d | | ||||||
|  |             | a | b | c | | ||||||
|  |             |   | e |   | | ||||||
|  | 
 | ||||||
|  |         And the ways | ||||||
|  |             | nodes | highway  | name  | | ||||||
|  |             | abc   | tertiary | road  | | ||||||
|  |             | cd    | tertiary | left  | | ||||||
|  |             | be    | tertiary | right | | ||||||
|  | 
 | ||||||
|  |         When I route I should get | ||||||
|  |             | waypoints | route            | turns                    | | ||||||
|  |             | a,d       | road,left,left   | depart,turn left,arrive  | | ||||||
|  |             | a,e       | road,right,right | depart,turn right,arrive | | ||||||
|  | 
 | ||||||
|  |     Scenario: No Name During Turns, keep important turns | ||||||
|  |         Given the node map | ||||||
|  |             | a | b | e | | ||||||
|  |             |   | c | d | | ||||||
|  | 
 | ||||||
|  |         And the ways | ||||||
|  |             | nodes | highway  | name  | | ||||||
|  |             | ab    | tertiary | road  | | ||||||
|  |             | bc    | tertiary |       | | ||||||
|  |             | cd    | tertiary | road  | | ||||||
|  |             | be    | tertiary | other | | ||||||
|  | 
 | ||||||
|  |         When I route I should get | ||||||
|  |             | waypoints | route          | turns                        | | ||||||
|  |             | a,d       | road,road,road | depart,continue right,arrive | | ||||||
|  | 
 | ||||||
|  | |||||||
| @ -119,7 +119,7 @@ Feature: Intersections Data | |||||||
|        When I route I should get |        When I route I should get | ||||||
|             | waypoints | route                  | turns                          | intersections                                                        | |             | waypoints | route                  | turns                          | intersections                                                        | | ||||||
|             | a,d       | through,through        | depart,arrive                  | true:90,true:0 true:90 false:270,true:90 true:180 false:270;true:270 | |             | a,d       | through,through        | depart,arrive                  | true:90,true:0 true:90 false:270,true:90 true:180 false:270;true:270 | | ||||||
|             | f,a       | corner,throughbridge,through | depart,end of road left,arrive | true:0;true:90 false:180 true:270,true:0 false:90 true:270;true:90   | |             | f,a       | corner,through,through | depart,end of road left,arrive | true:0;true:90 false:180 true:270,true:0 false:90 true:270;true:90   | | ||||||
| 
 | 
 | ||||||
|     Scenario: Roundabouts |     Scenario: Roundabouts | ||||||
|         Given the node map |         Given the node map | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ Feature: New-Name Instructions | |||||||
| 
 | 
 | ||||||
|     Background: |     Background: | ||||||
|         Given the profile "car" |         Given the profile "car" | ||||||
|         Given a grid size of 10 meters |         Given a grid size of 100 meters | ||||||
| 
 | 
 | ||||||
|     Scenario: Undisturbed name Change |     Scenario: Undisturbed name Change | ||||||
|         Given the node map |         Given the node map | ||||||
| @ -136,7 +136,7 @@ Feature: New-Name Instructions | |||||||
| 
 | 
 | ||||||
|     Scenario: Empty road names - Announce Change From, suppress Change To |     Scenario: Empty road names - Announce Change From, suppress Change To | ||||||
|         Given the node map |         Given the node map | ||||||
|             | a |  | b |  | c |  | d | |             | a |  | b | 1 | c |  | d | | ||||||
| 
 | 
 | ||||||
|         And the ways |         And the ways | ||||||
|             | nodes | name | |             | nodes | name | | ||||||
| @ -147,7 +147,7 @@ Feature: New-Name Instructions | |||||||
|         When I route I should get |         When I route I should get | ||||||
|             | waypoints | route    | turns                           | |             | waypoints | route    | turns                           | | ||||||
|             | a,d       | ab,cd,cd | depart,new name straight,arrive | |             | a,d       | ab,cd,cd | depart,new name straight,arrive | | ||||||
|             | a,c       | ab,      | depart,arrive                   | |             | a,1       | ab,      | depart,arrive                   | | ||||||
| 
 | 
 | ||||||
|     Scenario: Empty road names - Loose name shortly |     Scenario: Empty road names - Loose name shortly | ||||||
|         Given the node map |         Given the node map | ||||||
|  | |||||||
| @ -3,6 +3,7 @@ Feature: Alternative route | |||||||
| 
 | 
 | ||||||
|     Background: |     Background: | ||||||
|         Given the profile "testbot" |         Given the profile "testbot" | ||||||
|  |         And a grid size of 200 meters | ||||||
| 
 | 
 | ||||||
|         And the node map |         And the node map | ||||||
|             |   | b | c | d |   |   | |             |   | b | c | d |   |   | | ||||||
| @ -17,11 +18,11 @@ Feature: Alternative route | |||||||
|             | dz    | |             | dz    | | ||||||
|             | ag    | |             | ag    | | ||||||
|             | gh    | |             | gh    | | ||||||
|  |             | ck    | | ||||||
|  |             | kh    | | ||||||
|             | hi    | |             | hi    | | ||||||
|             | ij    | |             | ij    | | ||||||
|             | jz    | |             | jz    | | ||||||
|             | ck    | |  | ||||||
|             | kh    | |  | ||||||
| 
 | 
 | ||||||
|     Scenario: Enabled alternative |     Scenario: Enabled alternative | ||||||
|         Given the query options |         Given the query options | ||||||
|  | |||||||
| @ -56,7 +56,7 @@ Feature: Basic Routing | |||||||
| 
 | 
 | ||||||
|     Scenario: Two ways connected in a straight line |     Scenario: Two ways connected in a straight line | ||||||
|         Given the node map |         Given the node map | ||||||
|             | a | b | c | |             | a |   | b |   | c | | ||||||
| 
 | 
 | ||||||
|         And the ways |         And the ways | ||||||
|             | nodes | |             | nodes | | ||||||
|  | |||||||
| @ -43,8 +43,8 @@ Feature: Bearing parameter | |||||||
| 
 | 
 | ||||||
|     Scenario: Testbot - Initial bearing on split way |     Scenario: Testbot - Initial bearing on split way | ||||||
|         Given the node map |         Given the node map | ||||||
|         | d |  |  |  |  | 1 |  |  |  |  | c | |            | g | d |  |  |  |  | 1 |  |  |  |  | c | f | | ||||||
|         | a |  |  |  |  | 0 |  |  |  |  | b | |            | h | a |  |  |  |  | 0 |  |  |  |  | b | e | | ||||||
| 
 | 
 | ||||||
|         And the ways |         And the ways | ||||||
|             | nodes | oneway | |             | nodes | oneway | | ||||||
| @ -52,6 +52,10 @@ Feature: Bearing parameter | |||||||
|             | bc    | yes    | |             | bc    | yes    | | ||||||
|             | cd    | yes    | |             | cd    | yes    | | ||||||
|             | da    | yes    | |             | da    | yes    | | ||||||
|  |             | be    | yes    | | ||||||
|  |             | fc    | yes    | | ||||||
|  |             | dg    | yes    | | ||||||
|  |             | ha    | yes    | | ||||||
| 
 | 
 | ||||||
|         When I route I should get |         When I route I should get | ||||||
|             | from | to | bearings | route       | bearing       | |             | from | to | bearings | route       | bearing       | | ||||||
|  | |||||||
| @ -3,6 +3,7 @@ Feature: U-turns at via points | |||||||
| 
 | 
 | ||||||
|     Background: |     Background: | ||||||
|         Given the profile "testbot" |         Given the profile "testbot" | ||||||
|  |         Given a grid size of 100 meters | ||||||
| 
 | 
 | ||||||
|     Scenario: Continue straight at waypoints enabled by default |     Scenario: Continue straight at waypoints enabled by default | ||||||
|         Given the node map |         Given the node map | ||||||
|  | |||||||
| @ -11,6 +11,7 @@ Feature: Testbot - Travel mode | |||||||
| 
 | 
 | ||||||
|     Background: |     Background: | ||||||
|        Given the profile "testbot" |        Given the profile "testbot" | ||||||
|  |        Given a grid size of 200 meters | ||||||
| 
 | 
 | ||||||
|     Scenario: Testbot - Always announce mode change |     Scenario: Testbot - Always announce mode change | ||||||
|         Given the node map |         Given the node map | ||||||
| @ -73,8 +74,8 @@ Feature: Testbot - Travel mode | |||||||
| 
 | 
 | ||||||
|         When I route I should get |         When I route I should get | ||||||
|             | from | to | route | modes                 | time     | |             | from | to | route | modes                 | time     | | ||||||
|             | 0    | 1  | ab,ab | steps down,steps down | 60s +-1 | |             | 0    | 1  | ab,ab | steps down,steps down | 120s +-1 | | ||||||
|             | 1    | 0  | ab,ab | steps up,steps up     | 60s +-1 | |             | 1    | 0  | ab,ab | steps up,steps up     | 120s +-1 | | ||||||
| 
 | 
 | ||||||
|     @oneway |     @oneway | ||||||
|     Scenario: Testbot - Modes for oneway, different forward/backward speeds |     Scenario: Testbot - Modes for oneway, different forward/backward speeds | ||||||
|  | |||||||
| @ -3,6 +3,7 @@ Feature: Basic Routing | |||||||
| 
 | 
 | ||||||
|     Background: |     Background: | ||||||
|         Given the profile "testbot" |         Given the profile "testbot" | ||||||
|  |         Given a grid size of 200 meters | ||||||
| 
 | 
 | ||||||
|     @smallest |     @smallest | ||||||
|     Scenario: Checking |     Scenario: Checking | ||||||
|  | |||||||
| @ -144,6 +144,7 @@ class RouteAPI : public BaseAPI | |||||||
|                 guidance::trimShortSegments(steps, leg_geometry); |                 guidance::trimShortSegments(steps, leg_geometry); | ||||||
|                 leg.steps = guidance::postProcess(std::move(steps)); |                 leg.steps = guidance::postProcess(std::move(steps)); | ||||||
|                 leg.steps = guidance::collapseTurns(std::move(leg.steps)); |                 leg.steps = guidance::collapseTurns(std::move(leg.steps)); | ||||||
|  |                 leg.steps = guidance::buildIntersections(std::move(leg.steps)); | ||||||
|                 leg.steps = guidance::assignRelativeLocations(std::move(leg.steps), |                 leg.steps = guidance::assignRelativeLocations(std::move(leg.steps), | ||||||
|                                                               leg_geometry, |                                                               leg_geometry, | ||||||
|                                                               phantoms.source_phantom, |                                                               phantoms.source_phantom, | ||||||
|  | |||||||
| @ -37,6 +37,9 @@ std::vector<RouteStep> assignRelativeLocations(std::vector<RouteStep> steps, | |||||||
|                                                const PhantomNode &source_node, |                                                const PhantomNode &source_node, | ||||||
|                                                const PhantomNode &target_node); |                                                const PhantomNode &target_node); | ||||||
| 
 | 
 | ||||||
|  | // collapse suppressed instructions remaining into intersections array
 | ||||||
|  | std::vector<RouteStep> buildIntersections(std::vector<RouteStep> steps); | ||||||
|  | 
 | ||||||
| // remove steps invalidated by post-processing
 | // remove steps invalidated by post-processing
 | ||||||
| std::vector<RouteStep> removeNoTurnInstructions(std::vector<RouteStep> steps); | std::vector<RouteStep> removeNoTurnInstructions(std::vector<RouteStep> steps); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| #include "engine/guidance/post_processing.hpp" |  | ||||||
| #include "extractor/guidance/turn_instruction.hpp" | #include "extractor/guidance/turn_instruction.hpp" | ||||||
|  | #include "engine/guidance/post_processing.hpp" | ||||||
| 
 | 
 | ||||||
| #include "engine/guidance/assemble_steps.hpp" | #include "engine/guidance/assemble_steps.hpp" | ||||||
| #include "engine/guidance/toolkit.hpp" | #include "engine/guidance/toolkit.hpp" | ||||||
| @ -31,18 +31,49 @@ namespace guidance | |||||||
| 
 | 
 | ||||||
| namespace | namespace | ||||||
| { | { | ||||||
|  | const constexpr double MAX_COLLAPSE_DISTANCE = 25; | ||||||
|  | 
 | ||||||
|  | // List of types that can be collapsed, if all other restrictions pass
 | ||||||
|  | bool isCollapsableInstruction(const TurnInstruction instruction) | ||||||
|  | { | ||||||
|  |     return instruction.type == TurnType::NewName || | ||||||
|  |            (instruction.type == TurnType::Suppressed && | ||||||
|  |             instruction.direction_modifier == DirectionModifier::Straight) || | ||||||
|  |            (instruction.type == TurnType::Turn && | ||||||
|  |             instruction.direction_modifier == DirectionModifier::Straight); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // A check whether two instructions can be treated as one. This is only the case for very short
 | ||||||
|  | // maneuvers that can, in some form, be seen as one. The additional in_step is to find out about
 | ||||||
|  | // a possible u-turn.
 | ||||||
|  | bool collapsable(const RouteStep &step) | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  |     return step.distance < MAX_COLLAPSE_DISTANCE && | ||||||
|  |            isCollapsableInstruction(step.maneuver.instruction); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool compatible(const RouteStep &lhs, const RouteStep &rhs) { return lhs.mode == rhs.mode; } | ||||||
|  | 
 | ||||||
|  | double nameSegmentLength(std::size_t at, const std::vector<RouteStep> &steps) | ||||||
|  | { | ||||||
|  |     double result = steps[at].distance; | ||||||
|  |     while (at + 1 < steps.size() && steps[at + 1].name_id == steps[at].name_id) | ||||||
|  |     { | ||||||
|  |         ++at; | ||||||
|  |         result += steps[at].distance; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return result; | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| // invalidate a step and set its content to nothing
 | // invalidate a step and set its content to nothing
 | ||||||
| void invalidateStep(RouteStep &step) { step = getInvalidRouteStep(); } | void invalidateStep(RouteStep &step) { step = getInvalidRouteStep(); } | ||||||
| 
 | 
 | ||||||
| void print(const std::vector<RouteStep> &steps) | void print(const RouteStep &step) | ||||||
| { | { | ||||||
|     std::cout << "Path\n"; |     std::cout << static_cast<int>(step.maneuver.instruction.type) << " " | ||||||
|     int segment = 0; |               << static_cast<int>(step.maneuver.instruction.direction_modifier) << "  " | ||||||
|     for (const auto &step : steps) |  | ||||||
|     { |  | ||||||
|         std::cout << "\t[" << ++segment << "]: " << static_cast<int>(step.maneuver.instruction.type) |  | ||||||
|                   << " " << static_cast<int>(step.maneuver.instruction.direction_modifier) << "  " |  | ||||||
|               << static_cast<int>(step.maneuver.waypoint_type) << " Duration: " << step.duration |               << static_cast<int>(step.maneuver.waypoint_type) << " Duration: " << step.duration | ||||||
|               << " Distance: " << step.distance << " Geometry: " << step.geometry_begin << " " |               << " Distance: " << step.distance << " Geometry: " << step.geometry_begin << " " | ||||||
|               << step.geometry_end << " exit: " << step.maneuver.exit |               << step.geometry_end << " exit: " << step.maneuver.exit | ||||||
| @ -58,8 +89,18 @@ void print(const std::vector<RouteStep> &steps) | |||||||
|             std::cout << " " << entry; |             std::cout << " " << entry; | ||||||
|         std::cout << ")"; |         std::cout << ")"; | ||||||
|     } |     } | ||||||
|  |     std::cout << "] name[" << step.name_id << "]: " << step.name; | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
|         std::cout << "] name[" << step.name_id << "]: " << step.name << std::endl; | void print(const std::vector<RouteStep> &steps) | ||||||
|  | { | ||||||
|  |     std::cout << "Path\n"; | ||||||
|  |     int segment = 0; | ||||||
|  |     for (const auto &step : steps) | ||||||
|  |     { | ||||||
|  |         std::cout << "\t[" << segment++ << "]: "; | ||||||
|  |         print(step); | ||||||
|  |         std::cout << std::endl; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -327,15 +368,6 @@ RouteStep elongate(RouteStep step, const RouteStep &by_step) | |||||||
|     return step; |     return step; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // A check whether two instructions can be treated as one. This is only the case for very short
 |  | ||||||
| // maneuvers that can, in some form, be seen as one. The additional in_step is to find out about
 |  | ||||||
| // a possible u-turn.
 |  | ||||||
| bool collapsable(const RouteStep &step) |  | ||||||
| { |  | ||||||
|     const constexpr double MAX_COLLAPSE_DISTANCE = 25; |  | ||||||
|     return step.distance < MAX_COLLAPSE_DISTANCE; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void collapseTurnAt(std::vector<RouteStep> &steps, | void collapseTurnAt(std::vector<RouteStep> &steps, | ||||||
|                     const std::size_t two_back_index, |                     const std::size_t two_back_index, | ||||||
|                     const std::size_t one_back_index, |                     const std::size_t one_back_index, | ||||||
| @ -353,46 +385,59 @@ void collapseTurnAt(std::vector<RouteStep> &steps, | |||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     BOOST_ASSERT(!one_back_step.intersections.empty() && !current_step.intersections.empty()); |     BOOST_ASSERT(!one_back_step.intersections.empty() && !current_step.intersections.empty()); | ||||||
|     const auto isCollapsableInstruction = [](const TurnInstruction instruction) { |  | ||||||
|         return instruction.type == TurnType::NewName || |  | ||||||
|                (instruction.type == TurnType::Turn && |  | ||||||
|                 instruction.direction_modifier == DirectionModifier::Straight); |  | ||||||
|     }; |  | ||||||
|     // Very Short New Name
 |     // Very Short New Name
 | ||||||
|     if (isCollapsableInstruction(one_back_step.maneuver.instruction)) |     if (collapsable(one_back_step)) | ||||||
|     { |     { | ||||||
|         BOOST_ASSERT(two_back_index < steps.size()); |         BOOST_ASSERT(two_back_index < steps.size()); | ||||||
|         if (one_back_step.mode == steps[two_back_index].mode) |         if (compatible(one_back_step, steps[two_back_index])) | ||||||
|         { |         { | ||||||
|  |             BOOST_ASSERT(!one_back_step.intersections.empty()); | ||||||
|  |             if (TurnType::Continue == current_step.maneuver.instruction.type || | ||||||
|  |                 TurnType::Suppressed == current_step.maneuver.instruction.type) | ||||||
|  |                 steps[step_index].maneuver.instruction.type = TurnType::Turn; | ||||||
|  |             else if (TurnType::NewName == current_step.maneuver.instruction.type && | ||||||
|  |                      current_step.maneuver.instruction.direction_modifier != | ||||||
|  |                          DirectionModifier::Straight && | ||||||
|  |                      one_back_step.intersections.front().bearings.size() > 2) | ||||||
|  |                 steps[step_index].maneuver.instruction.type = TurnType::Turn; | ||||||
|  | 
 | ||||||
|             steps[two_back_index] = elongate(std::move(steps[two_back_index]), one_back_step); |             steps[two_back_index] = elongate(std::move(steps[two_back_index]), one_back_step); | ||||||
|             // If the previous instruction asked to continue, the name change will have to
 |             // If the previous instruction asked to continue, the name change will have to
 | ||||||
|             // be changed into a turn
 |             // be changed into a turn
 | ||||||
|             invalidateStep(steps[one_back_index]); |             invalidateStep(steps[one_back_index]); | ||||||
| 
 |  | ||||||
|             if (TurnType::Continue == current_step.maneuver.instruction.type) |  | ||||||
|                 steps[step_index].maneuver.instruction.type = TurnType::Turn; |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     // very short segment after turn
 |     // very short segment after turn
 | ||||||
|     else if (isCollapsableInstruction(current_step.maneuver.instruction)) |     else if (one_back_step.distance <= MAX_COLLAPSE_DISTANCE && | ||||||
|  |              isCollapsableInstruction(current_step.maneuver.instruction)) | ||||||
|     { |     { | ||||||
|         if (one_back_step.mode == current_step.mode) |         if (compatible(one_back_step, current_step)) | ||||||
|         { |         { | ||||||
|             steps[step_index] = elongate(std::move(steps[step_index]), steps[one_back_index]); |             steps[one_back_index] = elongate(std::move(steps[one_back_index]), steps[step_index]); | ||||||
|             invalidateStep(steps[one_back_index]); |             if ((TurnType::Continue == one_back_step.maneuver.instruction.type || | ||||||
| 
 |                  TurnType::Suppressed == one_back_step.maneuver.instruction.type) && | ||||||
|             if (TurnType::Continue == current_step.maneuver.instruction.type) |                 current_step.name_id != steps[two_back_index].name_id) | ||||||
|             { |             { | ||||||
|                 steps[step_index].maneuver.instruction.type = TurnType::Turn; |                 steps[one_back_index].maneuver.instruction.type = TurnType::Turn; | ||||||
|             } |             } | ||||||
|  |             else if (TurnType::Turn == one_back_step.maneuver.instruction.type && | ||||||
|  |                      current_step.name_id == steps[two_back_index].name_id) | ||||||
|  |             { | ||||||
|  |                 steps[one_back_index].maneuver.instruction.type = TurnType::Continue; | ||||||
|  |             } | ||||||
|  |             steps[one_back_index].name = current_step.name; | ||||||
|  |             steps[one_back_index].name_id = current_step.name_id; | ||||||
|  |             invalidateStep(steps[step_index]); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     // Potential U-Turn
 |     // Potential U-Turn
 | ||||||
|     else if (bearingsAreReversed(util::bearing::reverseBearing( |     else if (one_back_step.distance <= MAX_COLLAPSE_DISTANCE && | ||||||
|  |              bearingsAreReversed(util::bearing::reverseBearing( | ||||||
|                                      one_back_step.intersections.front() |                                      one_back_step.intersections.front() | ||||||
|                                          .bearings[one_back_step.intersections.front().in]), |                                          .bearings[one_back_step.intersections.front().in]), | ||||||
|                                  current_step.intersections.front() |                                  current_step.intersections.front() | ||||||
|                                      .bearings[current_step.intersections.front().out])) |                                      .bearings[current_step.intersections.front().out]) && | ||||||
|  |              compatible(one_back_step, current_step)) | ||||||
| 
 | 
 | ||||||
|     { |     { | ||||||
|         BOOST_ASSERT(two_back_index < steps.size()); |         BOOST_ASSERT(two_back_index < steps.size()); | ||||||
| @ -405,8 +450,7 @@ void collapseTurnAt(std::vector<RouteStep> &steps, | |||||||
|             (step_index + 1 < steps.size()) && |             (step_index + 1 < steps.size()) && | ||||||
|             isCollapsableInstruction(steps[step_index + 1].maneuver.instruction); |             isCollapsableInstruction(steps[step_index + 1].maneuver.instruction); | ||||||
|         const bool u_turn_with_name_change = |         const bool u_turn_with_name_change = | ||||||
|             collapsable(current_step) && continues_with_name_change && |             continues_with_name_change && steps[step_index + 1].name == steps[two_back_index].name; | ||||||
|             steps[step_index + 1].name == steps[two_back_index].name; |  | ||||||
| 
 | 
 | ||||||
|         if (direct_u_turn || u_turn_with_name_change) |         if (direct_u_turn || u_turn_with_name_change) | ||||||
|         { |         { | ||||||
| @ -518,13 +562,6 @@ std::vector<RouteStep> postProcess(std::vector<RouteStep> steps) | |||||||
|             has_entered_roundabout = false; |             has_entered_roundabout = false; | ||||||
|             on_roundabout = false; |             on_roundabout = false; | ||||||
|         } |         } | ||||||
|         else if (instruction.type == TurnType::Suppressed) |  | ||||||
|         { |  | ||||||
|             // count intersections. We cannot use exit, since intersections can follow directly
 |  | ||||||
|             // after a roundabout
 |  | ||||||
|             steps[last_valid_instruction] = elongate(steps[last_valid_instruction], step); |  | ||||||
|             step.maneuver.instruction = TurnInstruction::NO_TURN(); |  | ||||||
|         } |  | ||||||
|         else if (!isSilent(instruction)) |         else if (!isSilent(instruction)) | ||||||
|         { |         { | ||||||
|             // Remember the last non silent instruction
 |             // Remember the last non silent instruction
 | ||||||
| @ -564,58 +601,57 @@ std::vector<RouteStep> collapseTurns(std::vector<RouteStep> steps) | |||||||
|         BOOST_ASSERT(index > 0); |         BOOST_ASSERT(index > 0); | ||||||
|         BOOST_ASSERT(index < steps.size()); |         BOOST_ASSERT(index < steps.size()); | ||||||
|         --index; |         --index; | ||||||
|         while (index > 0 && steps[index].maneuver.instruction == TurnInstruction::NO_TURN()) |         while (index > 0 && steps[index].maneuver.instruction.type == TurnType::NoTurn) | ||||||
|             --index; |             --index; | ||||||
| 
 | 
 | ||||||
|         return index; |         return index; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     // Check for an initial unwanted new-name
 |     const auto getPreviousNameIndex = [&steps](std::size_t index) { | ||||||
|  |         BOOST_ASSERT(index > 0); | ||||||
|  |         BOOST_ASSERT(index < steps.size()); | ||||||
|  |         --index; // make sure to skip the current name
 | ||||||
|  |         while (index > 0 && steps[index].name_id == EMPTY_NAMEID) | ||||||
|         { |         { | ||||||
|         const auto ¤t_step = steps[1]; |             --index; | ||||||
|         if (TurnType::NewName == current_step.maneuver.instruction.type && |  | ||||||
|             current_step.name == steps[0].name) |  | ||||||
|         { |  | ||||||
|             steps[0] = elongate(std::move(steps[0]), steps[1]); |  | ||||||
|             invalidateStep(steps[1]); |  | ||||||
|         } |         } | ||||||
|     } |         return index; | ||||||
|     const auto isCollapsableInstruction = [](const TurnInstruction instruction) { |  | ||||||
|         return instruction.type == TurnType::NewName || |  | ||||||
|                (instruction.type == TurnType::Turn && |  | ||||||
|                 instruction.direction_modifier == DirectionModifier::Straight); |  | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     // Special case handling: if the phantomnode landed on a sliproad, we
 |     // a series of turns is only possible to collapse if its only name changes and suppressed turns.
 | ||||||
|     // change this into a 'turn' instruction.  Sliproads are small ramps
 |     const auto canCollapseAll = [&steps](std::size_t index, const std::size_t end_index) { | ||||||
|     // between roads, not ramps.
 |         BOOST_ASSERT(end_index <= steps.size()); | ||||||
|     if (steps.size() >= 3 && |         for (; index < end_index; ++index) | ||||||
|         steps[steps.size() - 2].maneuver.instruction.type == TurnType::Sliproad) |  | ||||||
|         { |         { | ||||||
|         steps[steps.size() - 2].maneuver.instruction.type = TurnType::Turn; |             if (steps[index].maneuver.instruction.type != TurnType::Suppressed && | ||||||
|  |                 steps[index].maneuver.instruction.type != TurnType::NewName) | ||||||
|  |                 return false; | ||||||
|         } |         } | ||||||
|  |         return true; | ||||||
|  |     }; | ||||||
| 
 | 
 | ||||||
|     // first and last instructions are waypoints that cannot be collapsed
 |     // first and last instructions are waypoints that cannot be collapsed
 | ||||||
|     for (std::size_t step_index = 2; step_index < steps.size(); ++step_index) |     for (std::size_t step_index = 1; step_index + 1 < steps.size(); ++step_index) | ||||||
|     { |     { | ||||||
|         const auto ¤t_step = steps[step_index]; |         const auto ¤t_step = steps[step_index]; | ||||||
|         const auto one_back_index = getPreviousIndex(step_index); |         const auto one_back_index = getPreviousIndex(step_index); | ||||||
|         BOOST_ASSERT(one_back_index < steps.size()); |         BOOST_ASSERT(one_back_index < steps.size()); | ||||||
| 
 | 
 | ||||||
|         // cannot collapse the depart instruction
 |  | ||||||
|         if (one_back_index == 0 || current_step.maneuver.instruction == TurnInstruction::NO_TURN()) |  | ||||||
|             continue; |  | ||||||
| 
 |  | ||||||
|         const auto &one_back_step = steps[one_back_index]; |         const auto &one_back_step = steps[one_back_index]; | ||||||
|         const auto two_back_index = getPreviousIndex(one_back_index); |         // how long has a name change to be so that we announce it, even as a bridge?
 | ||||||
|         BOOST_ASSERT(two_back_index < steps.size()); |         const constexpr auto name_segment_cutoff_length = 100; | ||||||
|  |         const auto isBasicNameChange = [](const RouteStep &step) { | ||||||
|  |             return step.intersections.size() == 1 && | ||||||
|  |                    step.intersections.front().bearings.size() == 2 && | ||||||
|  |                    DirectionModifier::Straight == step.maneuver.instruction.direction_modifier; | ||||||
|  |         }; | ||||||
| 
 | 
 | ||||||
|         // Handle sliproads from motorways in urban areas
 |         // Handle sliproads from motorways in urban areas, save from modifying depart, since
 | ||||||
|  |         // TurnType::Sliproad != TurnType::NoTurn
 | ||||||
|         if (one_back_step.maneuver.instruction.type == TurnType::Sliproad) |         if (one_back_step.maneuver.instruction.type == TurnType::Sliproad) | ||||||
|         { |         { | ||||||
| 
 |  | ||||||
|             // Handle possible u-turns between highways that look like slip-roads
 |             // Handle possible u-turns between highways that look like slip-roads
 | ||||||
|             if (steps[two_back_index].name_id == steps[step_index].name_id && |             if (steps[getPreviousIndex(one_back_index)].name_id == steps[step_index].name_id && | ||||||
|                 steps[step_index].name_id != EMPTY_NAMEID) |                 steps[step_index].name_id != EMPTY_NAMEID) | ||||||
|             { |             { | ||||||
|                 steps[one_back_index].maneuver.instruction.type = TurnType::Continue; |                 steps[one_back_index].maneuver.instruction.type = TurnType::Continue; | ||||||
| @ -624,7 +660,10 @@ std::vector<RouteStep> collapseTurns(std::vector<RouteStep> steps) | |||||||
|             { |             { | ||||||
|                 steps[one_back_index].maneuver.instruction.type = TurnType::Turn; |                 steps[one_back_index].maneuver.instruction.type = TurnType::Turn; | ||||||
|             } |             } | ||||||
|             steps[one_back_index] = elongate(std::move(steps[one_back_index]), steps[step_index]); |             if (compatible(one_back_step, current_step)) | ||||||
|  |             { | ||||||
|  |                 steps[one_back_index] = | ||||||
|  |                     elongate(std::move(steps[one_back_index]), steps[step_index]); | ||||||
|                 steps[one_back_index].name_id = steps[step_index].name_id; |                 steps[one_back_index].name_id = steps[step_index].name_id; | ||||||
|                 steps[one_back_index].name = steps[step_index].name; |                 steps[one_back_index].name = steps[step_index].name; | ||||||
| 
 | 
 | ||||||
| @ -640,26 +679,38 @@ std::vector<RouteStep> collapseTurns(std::vector<RouteStep> steps) | |||||||
|                     ::osrm::util::guidance::getTurnDirection(angle); |                     ::osrm::util::guidance::getTurnDirection(angle); | ||||||
|                 invalidateStep(steps[step_index]); |                 invalidateStep(steps[step_index]); | ||||||
|             } |             } | ||||||
|  |         } | ||||||
|         // Due to empty segments, we can get name-changes from A->A
 |         // Due to empty segments, we can get name-changes from A->A
 | ||||||
|         // These have to be handled in post-processing
 |         // These have to be handled in post-processing
 | ||||||
|         else if (isCollapsableInstruction(current_step.maneuver.instruction) && |         else if (isCollapsableInstruction(current_step.maneuver.instruction) && | ||||||
|                  current_step.name == steps[one_back_index].name) |                  current_step.maneuver.instruction.type != TurnType::Suppressed && | ||||||
|  |                  steps[getPreviousNameIndex(step_index)].name == current_step.name && | ||||||
|  |                  canCollapseAll(getPreviousNameIndex(step_index) + 1, step_index + 1)) | ||||||
|         { |         { | ||||||
|             steps[one_back_index] = elongate(std::move(steps[one_back_index]), steps[step_index]); |             BOOST_ASSERT(step_index > 0); | ||||||
|             invalidateStep(steps[step_index]); |             const std::size_t last_available_name_index = getPreviousNameIndex(step_index); | ||||||
|  | 
 | ||||||
|  |             for (std::size_t index = last_available_name_index + 1; index <= step_index; ++index) | ||||||
|  |             { | ||||||
|  |                 steps[last_available_name_index] = | ||||||
|  |                     elongate(std::move(steps[last_available_name_index]), steps[index]); | ||||||
|  |                 invalidateStep(steps[index]); | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|         // If we look at two consecutive name changes, we can check for a name oszillation.
 |         // If we look at two consecutive name changes, we can check for a name oszillation.
 | ||||||
|         // A name oszillation changes from name A shortly to name B and back to A.
 |         // A name oszillation changes from name A shortly to name B and back to A.
 | ||||||
|         // In these cases, the name change will be suppressed.
 |         // In these cases, the name change will be suppressed.
 | ||||||
|         else if (isCollapsableInstruction(current_step.maneuver.instruction) && |         else if (one_back_index > 0 && compatible(current_step, one_back_step) && | ||||||
|  |                  isCollapsableInstruction(current_step.maneuver.instruction) && | ||||||
|                  isCollapsableInstruction(one_back_step.maneuver.instruction)) |                  isCollapsableInstruction(one_back_step.maneuver.instruction)) | ||||||
|         { |         { | ||||||
|             // valid due to step_index starting at 2
 |             const auto two_back_index = getPreviousIndex(one_back_index); | ||||||
|  |             BOOST_ASSERT(two_back_index < steps.size()); | ||||||
|  |             // valid, since one_back is collapsable:
 | ||||||
|             const auto &coming_from_name = steps[two_back_index].name; |             const auto &coming_from_name = steps[two_back_index].name; | ||||||
|             if (current_step.name == coming_from_name) |             if (current_step.name == coming_from_name) | ||||||
|             { |             { | ||||||
|                 if (current_step.mode == one_back_step.mode && |                 if (compatible(one_back_step, steps[two_back_index])) | ||||||
|                     one_back_step.mode == steps[two_back_index].mode) |  | ||||||
|                 { |                 { | ||||||
|                     steps[two_back_index] = |                     steps[two_back_index] = | ||||||
|                         elongate(elongate(std::move(steps[two_back_index]), steps[one_back_index]), |                         elongate(elongate(std::move(steps[two_back_index]), steps[one_back_index]), | ||||||
| @ -670,13 +721,43 @@ std::vector<RouteStep> collapseTurns(std::vector<RouteStep> steps) | |||||||
|                 // TODO discuss: we could think about changing the new-name to a pure notification
 |                 // TODO discuss: we could think about changing the new-name to a pure notification
 | ||||||
|                 // about mode changes
 |                 // about mode changes
 | ||||||
|             } |             } | ||||||
|         } |             else if (nameSegmentLength(one_back_index, steps) < name_segment_cutoff_length && | ||||||
|         else if (collapsable(one_back_step)) |                      isBasicNameChange(one_back_step) && isBasicNameChange(current_step)) | ||||||
|             { |             { | ||||||
|             // check for one of the multiple collapse scenarios and, if possible, collapse the turn
 |                 steps[two_back_index] = | ||||||
|  |                     elongate(std::move(steps[two_back_index]), steps[one_back_index]); | ||||||
|  |                 invalidateStep(steps[one_back_index]); | ||||||
|  |                 if (nameSegmentLength(step_index, steps) < name_segment_cutoff_length) | ||||||
|  |                 { | ||||||
|  |                     steps[two_back_index] = | ||||||
|  |                         elongate(std::move(steps[two_back_index]), steps[step_index]); | ||||||
|  |                     invalidateStep(steps[step_index]); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             else if (one_back_step.distance <= MAX_COLLAPSE_DISTANCE) | ||||||
|  |             { | ||||||
|  |                 // check for one of the multiple collapse scenarios and, if possible, collapse the
 | ||||||
|  |                 // turn
 | ||||||
|  |                 const auto two_back_index = getPreviousIndex(one_back_index); | ||||||
|  |                 BOOST_ASSERT(two_back_index < steps.size()); | ||||||
|                 collapseTurnAt(steps, two_back_index, one_back_index, step_index); |                 collapseTurnAt(steps, two_back_index, one_back_index, step_index); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |         else if (one_back_index > 0 && one_back_step.distance <= MAX_COLLAPSE_DISTANCE) | ||||||
|  |         { | ||||||
|  |             // check for one of the multiple collapse scenarios and, if possible, collapse the turn
 | ||||||
|  |             const auto two_back_index = getPreviousIndex(one_back_index); | ||||||
|  |             BOOST_ASSERT(two_back_index < steps.size()); | ||||||
|  |             collapseTurnAt(steps, two_back_index, one_back_index, step_index); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // handle final sliproad
 | ||||||
|  |     if (steps.size() >= 3 && | ||||||
|  |         steps[steps.size() - 2].maneuver.instruction.type == TurnType::Sliproad) | ||||||
|  |     { | ||||||
|  |         steps[steps.size() - 2].maneuver.instruction.type = TurnType::Turn; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     BOOST_ASSERT(steps.front().intersections.size() >= 1); |     BOOST_ASSERT(steps.front().intersections.size() >= 1); | ||||||
|     BOOST_ASSERT(steps.front().intersections.front().bearings.size() == 1); |     BOOST_ASSERT(steps.front().intersections.front().bearings.size() == 1); | ||||||
| @ -700,7 +781,6 @@ std::vector<RouteStep> collapseTurns(std::vector<RouteStep> steps) | |||||||
| // usually not be as relevant.
 | // usually not be as relevant.
 | ||||||
| void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry) | void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry) | ||||||
| { | { | ||||||
| 
 |  | ||||||
|     if (steps.size() < 2 || geometry.locations.size() <= 2) |     if (steps.size() < 2 || geometry.locations.size() <= 2) | ||||||
|         return; |         return; | ||||||
| 
 | 
 | ||||||
| @ -955,6 +1035,29 @@ LegGeometry resyncGeometry(LegGeometry leg_geometry, const std::vector<RouteStep | |||||||
|     return leg_geometry; |     return leg_geometry; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | std::vector<RouteStep> buildIntersections(std::vector<RouteStep> steps) | ||||||
|  | { | ||||||
|  |     std::size_t last_valid_instruction = 0; | ||||||
|  |     for (std::size_t step_index = 0; step_index < steps.size(); ++step_index) | ||||||
|  |     { | ||||||
|  |         auto &step = steps[step_index]; | ||||||
|  |         const auto instruction = step.maneuver.instruction; | ||||||
|  |         if (instruction.type == TurnType::Suppressed) | ||||||
|  |         { | ||||||
|  |             // count intersections. We cannot use exit, since intersections can follow directly
 | ||||||
|  |             // after a roundabout
 | ||||||
|  |             steps[last_valid_instruction] = elongate(steps[last_valid_instruction], step); | ||||||
|  |             step.maneuver.instruction = TurnInstruction::NO_TURN(); | ||||||
|  |         } | ||||||
|  |         else if (!isSilent(instruction)) | ||||||
|  |         { | ||||||
|  |             // Remember the last non silent instruction
 | ||||||
|  |             last_valid_instruction = step_index; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return removeNoTurnInstructions(std::move(steps)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| } // namespace guidance
 | } // namespace guidance
 | ||||||
| } // namespace engine
 | } // namespace engine
 | ||||||
| } // namespace osrm
 | } // namespace osrm
 | ||||||
|  | |||||||
| @ -69,9 +69,6 @@ Intersection TurnHandler::handleTwoWayTurn(const EdgeID via_edge, Intersection i | |||||||
|     intersection[1].turn.instruction = |     intersection[1].turn.instruction = | ||||||
|         getInstructionForObvious(intersection.size(), via_edge, false, intersection[1]); |         getInstructionForObvious(intersection.size(), via_edge, false, intersection[1]); | ||||||
| 
 | 
 | ||||||
|     if (intersection[1].turn.instruction.type == TurnType::Suppressed) |  | ||||||
|         intersection[1].turn.instruction.type = TurnType::NoTurn; |  | ||||||
| 
 |  | ||||||
|     return intersection; |     return intersection; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user