Allow users to specify a class for each way
This adds the ability to mark ways with a user-defined class in the profile. This class information will be included in the response as property of the RouteStep object.
This commit is contained in:
		
							parent
							
								
									d52d530cbe
								
							
						
					
					
						commit
						44739f2dc3
					
				| @ -5,8 +5,11 @@ | |||||||
|         - Plugins supported: `table` |         - Plugins supported: `table` | ||||||
|     - API: |     - API: | ||||||
|       - Support for exits numbers and names. New member `exits` in `RouteStep`, based on `junction:ref` on ways |       - Support for exits numbers and names. New member `exits` in `RouteStep`, based on `junction:ref` on ways | ||||||
|  |       - `RouteStep` now has new parameter `classes` that can be set in the profile on each way. | ||||||
|     - Profiles: |     - Profiles: | ||||||
|         - `result.exits` allows you to set a way's exit numbers and names, see [`junction:ref`](http://wiki.openstreetmap.org/wiki/Proposed_features/junction_details) |         - `result.exits` allows you to set a way's exit numbers and names, see [`junction:ref`](http://wiki.openstreetmap.org/wiki/Proposed_features/junction_details) | ||||||
|  |         - `ExtractionWay` now as new property `forward_classes` and `backward_classes` that can set in the `way_function`. | ||||||
|  |            The maximum number of classes is 8. | ||||||
| 
 | 
 | ||||||
| # 5.8.0 | # 5.8.0 | ||||||
|   - Changes from 5.7 |   - Changes from 5.7 | ||||||
|  | |||||||
| @ -583,6 +583,7 @@ step. | |||||||
| - `destinations`: The destinations of the way. Will be `undefined` if there are no destinations. | - `destinations`: The destinations of the way. Will be `undefined` if there are no destinations. | ||||||
| - `exits`: The exit numbers or names of the way. Will be `undefined` if there are no exit numbers or names. | - `exits`: The exit numbers or names of the way. Will be `undefined` if there are no exit numbers or names. | ||||||
| - `mode`: A string signifying the mode of transportation. | - `mode`: A string signifying the mode of transportation. | ||||||
|  | - `classes`: An array of strings signifying the classes of the road as specified in the profile. | ||||||
| - `maneuver`: A `StepManeuver` object representing the maneuver. | - `maneuver`: A `StepManeuver` object representing the maneuver. | ||||||
| - `intersections`: A list of `Intersection` objects that are passed along the segment, the very first belonging to the StepManeuver | - `intersections`: A list of `Intersection` objects that are passed along the segment, the very first belonging to the StepManeuver | ||||||
| - `rotary_name`: The name for the rotary. Optionally included, if the step is a rotary and a rotary name is available. | - `rotary_name`: The name for the rotary. Optionally included, if the step is a rotary and a rotary name is available. | ||||||
| @ -596,6 +597,7 @@ step. | |||||||
|    "mode" : "driving", |    "mode" : "driving", | ||||||
|    "duration" : 15.6, |    "duration" : 15.6, | ||||||
|    "weight" : 15.6, |    "weight" : 15.6, | ||||||
|  |    "classes": ["toll", "restricted"], | ||||||
|    "intersections" : [ |    "intersections" : [ | ||||||
|       {  "bearings" : [ 10, 92, 184, 270 ], |       {  "bearings" : [ 10, 92, 184, 270 ], | ||||||
|          "lanes" : [ |          "lanes" : [ | ||||||
| @ -660,7 +662,7 @@ step. | |||||||
| | `roundabout`     | traverse roundabout, has additional property `exit` with NR if the roundabout is left. The modifier specifies the direction of entering the roundabout. | | | `roundabout`     | traverse roundabout, has additional property `exit` with NR if the roundabout is left. The modifier specifies the direction of entering the roundabout. | | ||||||
| | `rotary`         | a traffic circle. While very similar to a larger version of a roundabout, it does not necessarily follow roundabout rules for right of way. It can offer `rotary_name` and/or `rotary_pronunciation` parameters (located in the RouteStep object) in addition to the `exit` parameter (located on the StepManeuver object).  | | | `rotary`         | a traffic circle. While very similar to a larger version of a roundabout, it does not necessarily follow roundabout rules for right of way. It can offer `rotary_name` and/or `rotary_pronunciation` parameters (located in the RouteStep object) in addition to the `exit` parameter (located on the StepManeuver object).  | | ||||||
| | `roundabout turn`| Describes a turn at a small roundabout that should be treated as normal turn. The `modifier` indicates the turn direciton. Example instruction: `At the roundabout turn left`. | | | `roundabout turn`| Describes a turn at a small roundabout that should be treated as normal turn. The `modifier` indicates the turn direciton. Example instruction: `At the roundabout turn left`. | | ||||||
| | `notification`   | not an actual turn but a change in the driving conditions. For example the travel mode.  If the road takes a turn itself, the `modifier` describes the direction | | | `notification`   | not an actual turn but a change in the driving conditions. For example the travel mode or classes. If the road takes a turn itself, the `modifier` describes the direction | | ||||||
| 
 | 
 | ||||||
|   Please note that even though there are `new name` and `notification` instructions, the `mode` and `name` can change |   Please note that even though there are `new name` and `notification` instructions, the `mode` and `name` can change | ||||||
|   between all instructions. They only offer a fallback in case nothing else is to report. |   between all instructions. They only offer a fallback in case nothing else is to report. | ||||||
|  | |||||||
| @ -56,6 +56,8 @@ forward_rate                            | Float    | Routing weight, expressed a | |||||||
| backward_rate                           | Float    |  "   " | backward_rate                           | Float    |  "   " | ||||||
| forward_mode                            | Enum     | Mode of travel (e.g. `car`, `ferry`). Mandatory. Defined in `include/extractor/travel_mode.hpp`. | forward_mode                            | Enum     | Mode of travel (e.g. `car`, `ferry`). Mandatory. Defined in `include/extractor/travel_mode.hpp`. | ||||||
| backward_mode                           | Enum     |  "   " | backward_mode                           | Enum     |  "   " | ||||||
|  | forward_classes                         | Table    | Mark this way as being of a specific class, e.g. `result.classes["toll"] = true`. This will be exposed in the API as `classes` on each `RouteStep`. | ||||||
|  | backward_classes                        | Table    |  "   " | ||||||
| duration                                | Float    | Alternative setter for duration of the whole way in both directions | duration                                | Float    | Alternative setter for duration of the whole way in both directions | ||||||
| weight                                  | Float    | Alternative setter for weight of the whole way in both directions | weight                                  | Float    | Alternative setter for weight of the whole way in both directions | ||||||
| turn_lanes_forward                      | String   | Directions for individual lanes (normalised OSM `turn:lanes` value) | turn_lanes_forward                      | String   | Directions for individual lanes (normalised OSM `turn:lanes` value) | ||||||
|  | |||||||
							
								
								
									
										101
									
								
								features/car/classes.feature
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								features/car/classes.feature
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,101 @@ | |||||||
|  | @routing @car @mode | ||||||
|  | Feature: Car - Mode flag | ||||||
|  |     Background: | ||||||
|  |         Given the profile "car" | ||||||
|  | 
 | ||||||
|  |     Scenario: Car - We tag ferries with a class | ||||||
|  |         Given the node map | ||||||
|  |             """ | ||||||
|  |             a b | ||||||
|  |               c d | ||||||
|  |             """ | ||||||
|  | 
 | ||||||
|  |         And the ways | ||||||
|  |             | nodes | highway | route | | ||||||
|  |             | ab    | primary |       | | ||||||
|  |             | bc    |         | ferry | | ||||||
|  |             | cd    | primary |       | | ||||||
|  | 
 | ||||||
|  |         When I route I should get | ||||||
|  |             | from | to | route       | turns                                              | classes      | | ||||||
|  |             | a    | d  | ab,bc,cd,cd | depart,notification right,notification left,arrive | ,ferry,,     | | ||||||
|  |             | d    | a  | cd,bc,ab,ab | depart,notification right,notification left,arrive | ,ferry,,     | | ||||||
|  |             | c    | a  | bc,ab,ab    | depart,notification left,arrive                    | ferry,,      | | ||||||
|  |             | d    | b  | cd,bc,bc    | depart,notification right,arrive                   | ,ferry,ferry | | ||||||
|  |             | a    | c  | ab,bc,bc    | depart,notification right,arrive                   | ,ferry,ferry | | ||||||
|  |             | b    | d  | bc,cd,cd    | depart,notification left,arrive                    | ferry,,      | | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     Scenario: Car - We tag motorways with a class | ||||||
|  |         Given the node map | ||||||
|  |             """ | ||||||
|  |             a b | ||||||
|  |               c d | ||||||
|  |             """ | ||||||
|  | 
 | ||||||
|  |         And the ways | ||||||
|  |             | nodes | highway | | ||||||
|  |             | ab    | primary | | ||||||
|  |             | bc    | motorway| | ||||||
|  |             | cd    | primary | | ||||||
|  | 
 | ||||||
|  |         When I route I should get | ||||||
|  |             | from | to | route    | turns                            | classes            | #                                           | | ||||||
|  |             | a    | d  | ab,bc,cd | depart,notification right,arrive | ,motorway,         |                                             | | ||||||
|  |             | a    | c  | ab,bc,bc | depart,notification right,arrive | ,motorway,motorway |                                             | | ||||||
|  |             | b    | d  | bc,cd    | depart,arrive                    | motorway,          | we don't announce when we leave the highway | | ||||||
|  | 
 | ||||||
|  |     Scenario: Car - We tag motorway_link with a class | ||||||
|  |         Given the node map | ||||||
|  |             """ | ||||||
|  |             a b | ||||||
|  |               c d | ||||||
|  |             """ | ||||||
|  | 
 | ||||||
|  |         And the ways | ||||||
|  |             | nodes | highway       | | ||||||
|  |             | ab    | primary       | | ||||||
|  |             | bc    | motorway_link | | ||||||
|  |             | cd    | primary       | | ||||||
|  | 
 | ||||||
|  |         When I route I should get | ||||||
|  |             | from | to | route    | turns                       | classes            | #                                | | ||||||
|  |             | a    | d  | ab,bc,cd | depart,on ramp right,arrive | ,motorway,         | notification replaced by on-ramp | | ||||||
|  |             | a    | c  | ab,bc,bc | depart,on ramp right,arrive | ,motorway,motorway |    "                "            | | ||||||
|  |             | b    | d  | bc,cd    | depart,arrive               | motorway,          | no announcement                  | | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     Scenario: Car - We tag restricted with a class | ||||||
|  |         Given the node map | ||||||
|  |             """ | ||||||
|  |             a b | ||||||
|  |               c d | ||||||
|  |             """ | ||||||
|  | 
 | ||||||
|  |         And the ways | ||||||
|  |             | nodes | highway | access   | | ||||||
|  |             | ab    | primary | private  | | ||||||
|  |             | bc    | motorway| private  | | ||||||
|  |             | cd    | primary |          | | ||||||
|  | 
 | ||||||
|  |         When I route I should get | ||||||
|  |             | from | to | route    | turns                           | classes                         | | ||||||
|  |             | a    | d  | ab,bc,cd | depart,notification right,arrive| restricted,motorway;restricted, | | ||||||
|  | 
 | ||||||
|  |     Scenario: Car - We toll restricted with a class | ||||||
|  |         Given the node map | ||||||
|  |             """ | ||||||
|  |             a b | ||||||
|  |               c d | ||||||
|  |             """ | ||||||
|  | 
 | ||||||
|  |         And the ways | ||||||
|  |             | nodes | highway | toll     | | ||||||
|  |             | ab    | primary | yes      | | ||||||
|  |             | bc    | motorway| yes      | | ||||||
|  |             | cd    | primary |          | | ||||||
|  | 
 | ||||||
|  |         When I route I should get | ||||||
|  |             | from | to | route    | turns                            | classes             | | ||||||
|  |             | a    | d  | ab,bc,cd | depart,notification right,arrive | toll,motorway;toll, | | ||||||
|  | 
 | ||||||
| @ -23,11 +23,11 @@ Feature: Car - Destination only, no passing through | |||||||
|         When I route I should get |         When I route I should get | ||||||
|             | from | to | route      | |             | from | to | route      | | ||||||
|             | a    | b  | ab,ab      | |             | a    | b  | ab,ab      | | ||||||
|             | a    | c  | ab,bcd     | |             | a    | c  | ab,bcd,bcd | | ||||||
|             | a    | d  | ab,bcd,bcd | |             | a    | d  | ab,bcd,bcd | | ||||||
|             | a    | e  | axye,axye  | |             | a    | e  | axye,axye  | | ||||||
|             | e    | d  | de,de      | |             | e    | d  | de,de      | | ||||||
|             | e    | c  | de,bcd     | |             | e    | c  | de,bcd,bcd | | ||||||
|             | e    | b  | de,bcd,bcd | |             | e    | b  | de,bcd,bcd | | ||||||
|             | e    | a  | axye,axye  | |             | e    | a  | axye,axye  | | ||||||
| 
 | 
 | ||||||
| @ -51,12 +51,12 @@ Feature: Car - Destination only, no passing through | |||||||
|         When I route I should get |         When I route I should get | ||||||
|             | from | to | route       | |             | from | to | route       | | ||||||
|             | a    | b  | ab,ab       | |             | a    | b  | ab,ab       | | ||||||
|             | a    | c  | ab,bc       | |             | a    | c  | ab,bc,bc    | | ||||||
|             | a    | d  | ab,cd       | |             | a    | d  | ab,bc,cd    | | ||||||
|             | a    | e  | axye,axye   | |             | a    | e  | axye,axye   | | ||||||
|             | e    | d  | de,de       | |             | e    | d  | de,de       | | ||||||
|             | e    | c  | de,cd       | |             | e    | c  | de,cd,cd    | | ||||||
|             | e    | b  | de,bc       | |             | e    | b  | de,cd,bc    | | ||||||
|             | e    | a  | axye,axye   | |             | e    | a  | axye,axye   | | ||||||
| 
 | 
 | ||||||
|     Scenario: Car - Routing inside a destination only area |     Scenario: Car - Routing inside a destination only area | ||||||
|  | |||||||
| @ -260,6 +260,10 @@ module.exports = function () { | |||||||
|         return this.extractInstructionList(instructions, s => s.mode); |         return this.extractInstructionList(instructions, s => s.mode); | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  |     this.classesList = (instructions) => { | ||||||
|  |         return this.extractInstructionList(instructions, s => s.classes ? s.classes.join(';') : ''); | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|     this.timeList = (instructions) => { |     this.timeList = (instructions) => { | ||||||
|         return this.extractInstructionList(instructions, s => s.duration + 's'); |         return this.extractInstructionList(instructions, s => s.duration + 's'); | ||||||
|     }; |     }; | ||||||
|  | |||||||
| @ -34,7 +34,7 @@ module.exports = function () { | |||||||
|                 var afterRequest = (err, res, body) => { |                 var afterRequest = (err, res, body) => { | ||||||
|                     if (err) return cb(err); |                     if (err) return cb(err); | ||||||
|                     if (body && body.length) { |                     if (body && body.length) { | ||||||
|                         let destinations, exits, pronunciations, instructions, refs, bearings, turns, modes, times, |                         let destinations, exits, pronunciations, instructions, refs, bearings, turns, modes, times, classes, | ||||||
|                             distances, summary, intersections, lanes, locations, annotation, weight_name, weights, approaches; |                             distances, summary, intersections, lanes, locations, annotation, weight_name, weights, approaches; | ||||||
| 
 | 
 | ||||||
|                         let json = JSON.parse(body); |                         let json = JSON.parse(body); | ||||||
| @ -53,6 +53,7 @@ module.exports = function () { | |||||||
|                             turns = this.turnList(json.routes[0]); |                             turns = this.turnList(json.routes[0]); | ||||||
|                             intersections = this.intersectionList(json.routes[0]); |                             intersections = this.intersectionList(json.routes[0]); | ||||||
|                             modes = this.modeList(json.routes[0]); |                             modes = this.modeList(json.routes[0]); | ||||||
|  |                             classes = this.classesList(json.routes[0]); | ||||||
|                             times = this.timeList(json.routes[0]); |                             times = this.timeList(json.routes[0]); | ||||||
|                             distances = this.distanceList(json.routes[0]); |                             distances = this.distanceList(json.routes[0]); | ||||||
|                             lanes = this.lanesList(json.routes[0]); |                             lanes = this.lanesList(json.routes[0]); | ||||||
| @ -174,6 +175,7 @@ module.exports = function () { | |||||||
|                         putValue('bearing', bearings); |                         putValue('bearing', bearings); | ||||||
|                         putValue('turns', turns); |                         putValue('turns', turns); | ||||||
|                         putValue('modes', modes); |                         putValue('modes', modes); | ||||||
|  |                         putValue('classes', classes); | ||||||
|                         putValue('times', times); |                         putValue('times', times); | ||||||
|                         putValue('distances', distances); |                         putValue('distances', distances); | ||||||
|                         putValue('pronunciations', pronunciations); |                         putValue('pronunciations', pronunciations); | ||||||
|  | |||||||
| @ -318,7 +318,7 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade | |||||||
|     void InitializeEdgeBasedNodeDataInformationPointers(storage::DataLayout &layout, |     void InitializeEdgeBasedNodeDataInformationPointers(storage::DataLayout &layout, | ||||||
|                                                         char *memory_ptr) |                                                         char *memory_ptr) | ||||||
|     { |     { | ||||||
|         auto via_geometry_list_ptr = |         const auto via_geometry_list_ptr = | ||||||
|             layout.GetBlockPtr<GeometryID>(memory_ptr, storage::DataLayout::GEOMETRY_ID_LIST); |             layout.GetBlockPtr<GeometryID>(memory_ptr, storage::DataLayout::GEOMETRY_ID_LIST); | ||||||
|         util::vector_view<GeometryID> geometry_ids( |         util::vector_view<GeometryID> geometry_ids( | ||||||
|             via_geometry_list_ptr, layout.num_entries[storage::DataLayout::GEOMETRY_ID_LIST]); |             via_geometry_list_ptr, layout.num_entries[storage::DataLayout::GEOMETRY_ID_LIST]); | ||||||
| @ -338,10 +338,16 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade | |||||||
|         util::vector_view<extractor::TravelMode> travel_modes( |         util::vector_view<extractor::TravelMode> travel_modes( | ||||||
|             travel_mode_list_ptr, layout.num_entries[storage::DataLayout::TRAVEL_MODE_LIST]); |             travel_mode_list_ptr, layout.num_entries[storage::DataLayout::TRAVEL_MODE_LIST]); | ||||||
| 
 | 
 | ||||||
|  |         const auto classes_list_ptr = | ||||||
|  |             layout.GetBlockPtr<extractor::ClassData>(memory_ptr, storage::DataLayout::CLASSES_LIST); | ||||||
|  |         util::vector_view<extractor::ClassData> classes( | ||||||
|  |             classes_list_ptr, layout.num_entries[storage::DataLayout::CLASSES_LIST]); | ||||||
|  | 
 | ||||||
|         edge_based_node_data = extractor::EdgeBasedNodeDataView(std::move(geometry_ids), |         edge_based_node_data = extractor::EdgeBasedNodeDataView(std::move(geometry_ids), | ||||||
|                                                                 std::move(name_ids), |                                                                 std::move(name_ids), | ||||||
|                                                                 std::move(component_ids), |                                                                 std::move(component_ids), | ||||||
|                                                                 std::move(travel_modes)); |                                                                 std::move(travel_modes), | ||||||
|  |                                                                 std::move(classes)); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     void InitializeEdgeInformationPointers(storage::DataLayout &layout, char *memory_ptr) |     void InitializeEdgeInformationPointers(storage::DataLayout &layout, char *memory_ptr) | ||||||
| @ -783,6 +789,22 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade | |||||||
|         return edge_based_node_data.GetTravelMode(id); |         return edge_based_node_data.GetTravelMode(id); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     extractor::ClassData GetClassData(const NodeID id) const override final | ||||||
|  |     { | ||||||
|  |         return edge_based_node_data.GetClassData(id); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     std::vector<std::string> GetClasses(const extractor::ClassData class_data) const override final | ||||||
|  |     { | ||||||
|  |         auto indexes = extractor::getClassIndexes(class_data); | ||||||
|  |         std::vector<std::string> classes(indexes.size()); | ||||||
|  |         std::transform(indexes.begin(), indexes.end(), classes.begin(), [this](const auto index) { | ||||||
|  |             return m_profile_properties->GetClassName(index); | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         return classes; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     NameID GetNameIndex(const NodeID id) const override final |     NameID GetNameIndex(const NodeID id) const override final | ||||||
|     { |     { | ||||||
|         return edge_based_node_data.GetNameID(id); |         return edge_based_node_data.GetNameID(id); | ||||||
|  | |||||||
| @ -3,14 +3,19 @@ | |||||||
| 
 | 
 | ||||||
| // Exposes all data access interfaces to the algorithms via base class ptr
 | // Exposes all data access interfaces to the algorithms via base class ptr
 | ||||||
| 
 | 
 | ||||||
|  | #include "engine/approach.hpp" | ||||||
|  | #include "engine/phantom_node.hpp" | ||||||
|  | 
 | ||||||
| #include "contractor/query_edge.hpp" | #include "contractor/query_edge.hpp" | ||||||
|  | 
 | ||||||
|  | #include "extractor/class_data.hpp" | ||||||
| #include "extractor/edge_based_node_segment.hpp" | #include "extractor/edge_based_node_segment.hpp" | ||||||
| #include "extractor/external_memory_node.hpp" | #include "extractor/external_memory_node.hpp" | ||||||
| #include "extractor/guidance/turn_instruction.hpp" | #include "extractor/guidance/turn_instruction.hpp" | ||||||
| #include "extractor/guidance/turn_lane_types.hpp" | #include "extractor/guidance/turn_lane_types.hpp" | ||||||
| #include "extractor/original_edge_data.hpp" | #include "extractor/original_edge_data.hpp" | ||||||
| #include "engine/approach.hpp" | #include "extractor/travel_mode.hpp" | ||||||
| #include "engine/phantom_node.hpp" | 
 | ||||||
| #include "util/exception.hpp" | #include "util/exception.hpp" | ||||||
| #include "util/guidance/bearing_class.hpp" | #include "util/guidance/bearing_class.hpp" | ||||||
| #include "util/guidance/entry_class.hpp" | #include "util/guidance/entry_class.hpp" | ||||||
| @ -87,6 +92,10 @@ class BaseDataFacade | |||||||
| 
 | 
 | ||||||
|     virtual extractor::TravelMode GetTravelMode(const NodeID id) const = 0; |     virtual extractor::TravelMode GetTravelMode(const NodeID id) const = 0; | ||||||
| 
 | 
 | ||||||
|  |     virtual extractor::ClassData GetClassData(const NodeID id) const = 0; | ||||||
|  | 
 | ||||||
|  |     virtual std::vector<std::string> GetClasses(const extractor::ClassData class_data) const = 0; | ||||||
|  | 
 | ||||||
|     virtual std::vector<RTreeLeaf> GetEdgesInBox(const util::Coordinate south_west, |     virtual std::vector<RTreeLeaf> GetEdgesInBox(const util::Coordinate south_west, | ||||||
|                                                  const util::Coordinate north_east) const = 0; |                                                  const util::Coordinate north_east) const = 0; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -53,6 +53,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa | |||||||
|                                                             : source_node.forward_segment_id.id; |                                                             : source_node.forward_segment_id.id; | ||||||
|     const auto source_name_id = facade.GetNameIndex(source_node_id); |     const auto source_name_id = facade.GetNameIndex(source_node_id); | ||||||
|     const auto source_mode = facade.GetTravelMode(source_node_id); |     const auto source_mode = facade.GetTravelMode(source_node_id); | ||||||
|  |     auto source_classes = facade.GetClasses(facade.GetClassData(source_node_id)); | ||||||
| 
 | 
 | ||||||
|     const EdgeWeight target_duration = |     const EdgeWeight target_duration = | ||||||
|         target_traversed_in_reverse ? target_node.reverse_duration : target_node.forward_duration; |         target_traversed_in_reverse ? target_node.reverse_duration : target_node.forward_duration; | ||||||
| @ -62,6 +63,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa | |||||||
|                                                             : target_node.forward_segment_id.id; |                                                             : target_node.forward_segment_id.id; | ||||||
|     const auto target_name_id = facade.GetNameIndex(target_node_id); |     const auto target_name_id = facade.GetNameIndex(target_node_id); | ||||||
|     const auto target_mode = facade.GetTravelMode(target_node_id); |     const auto target_mode = facade.GetTravelMode(target_node_id); | ||||||
|  |     auto target_classes = facade.GetClasses(facade.GetClassData(target_node_id)); | ||||||
| 
 | 
 | ||||||
|     const auto number_of_segments = leg_geometry.GetNumberOfSegments(); |     const auto number_of_segments = leg_geometry.GetNumberOfSegments(); | ||||||
| 
 | 
 | ||||||
| @ -116,6 +118,7 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa | |||||||
|                 const auto destinations = facade.GetDestinationsForID(step_name_id); |                 const auto destinations = facade.GetDestinationsForID(step_name_id); | ||||||
|                 const auto exits = facade.GetExitsForID(step_name_id); |                 const auto exits = facade.GetExitsForID(step_name_id); | ||||||
|                 const auto distance = leg_geometry.segment_distances[segment_index]; |                 const auto distance = leg_geometry.segment_distances[segment_index]; | ||||||
|  |                 auto classes = facade.GetClasses(path_point.classes); | ||||||
| 
 | 
 | ||||||
|                 steps.push_back(RouteStep{step_name_id, |                 steps.push_back(RouteStep{step_name_id, | ||||||
|                                           name.to_string(), |                                           name.to_string(), | ||||||
| @ -132,7 +135,8 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa | |||||||
|                                           maneuver, |                                           maneuver, | ||||||
|                                           leg_geometry.FrontIndex(segment_index), |                                           leg_geometry.FrontIndex(segment_index), | ||||||
|                                           leg_geometry.BackIndex(segment_index) + 1, |                                           leg_geometry.BackIndex(segment_index) + 1, | ||||||
|                                           {intersection}}); |                                           {intersection}, | ||||||
|  |                                           std::move(classes)}); | ||||||
| 
 | 
 | ||||||
|                 if (leg_data_index + 1 < leg_data.size()) |                 if (leg_data_index + 1 < leg_data.size()) | ||||||
|                 { |                 { | ||||||
| @ -208,7 +212,8 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa | |||||||
|                                   maneuver, |                                   maneuver, | ||||||
|                                   leg_geometry.FrontIndex(segment_index), |                                   leg_geometry.FrontIndex(segment_index), | ||||||
|                                   leg_geometry.BackIndex(segment_index) + 1, |                                   leg_geometry.BackIndex(segment_index) + 1, | ||||||
|                                   {intersection}}); |                                   {intersection}, | ||||||
|  |                                   std::move(target_classes)}); | ||||||
|     } |     } | ||||||
|     // In this case the source + target are on the same edge segment
 |     // In this case the source + target are on the same edge segment
 | ||||||
|     else |     else | ||||||
| @ -250,7 +255,8 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa | |||||||
|                                   std::move(maneuver), |                                   std::move(maneuver), | ||||||
|                                   leg_geometry.FrontIndex(segment_index), |                                   leg_geometry.FrontIndex(segment_index), | ||||||
|                                   leg_geometry.BackIndex(segment_index) + 1, |                                   leg_geometry.BackIndex(segment_index) + 1, | ||||||
|                                   {intersection}}); |                                   {intersection}, | ||||||
|  |                                   std::move(source_classes)}); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     BOOST_ASSERT(segment_index == number_of_segments - 1); |     BOOST_ASSERT(segment_index == number_of_segments - 1); | ||||||
| @ -289,7 +295,8 @@ inline std::vector<RouteStep> assembleSteps(const datafacade::BaseDataFacade &fa | |||||||
|                               std::move(maneuver), |                               std::move(maneuver), | ||||||
|                               leg_geometry.locations.size() - 1, |                               leg_geometry.locations.size() - 1, | ||||||
|                               leg_geometry.locations.size(), |                               leg_geometry.locations.size(), | ||||||
|                               {intersection}}); |                               {intersection}, | ||||||
|  |                               std::move(target_classes)}); | ||||||
| 
 | 
 | ||||||
|     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); | ||||||
|  | |||||||
| @ -74,6 +74,7 @@ struct RouteStep | |||||||
|     std::size_t geometry_begin; |     std::size_t geometry_begin; | ||||||
|     std::size_t geometry_end; |     std::size_t geometry_end; | ||||||
|     std::vector<IntermediateIntersection> intersections; |     std::vector<IntermediateIntersection> intersections; | ||||||
|  |     std::vector<std::string> classes; | ||||||
| 
 | 
 | ||||||
|     // remove all information from the route step, marking it as invalid (used to indicate empty
 |     // remove all information from the route step, marking it as invalid (used to indicate empty
 | ||||||
|     // steps to be removed).
 |     // steps to be removed).
 | ||||||
| @ -127,6 +128,7 @@ inline void RouteStep::Invalidate() | |||||||
|     geometry_end = 0; |     geometry_end = 0; | ||||||
|     intersections.clear(); |     intersections.clear(); | ||||||
|     intersections.push_back(getInvalidIntersection()); |     intersections.push_back(getInvalidIntersection()); | ||||||
|  |     classes.clear(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Elongate by another step in front
 | // Elongate by another step in front
 | ||||||
|  | |||||||
| @ -33,6 +33,8 @@ struct PathData | |||||||
|     util::guidance::LaneTupleIdPair lane_data; |     util::guidance::LaneTupleIdPair lane_data; | ||||||
|     // travel mode of the street that leads to the turn
 |     // travel mode of the street that leads to the turn
 | ||||||
|     extractor::TravelMode travel_mode : 4; |     extractor::TravelMode travel_mode : 4; | ||||||
|  |     // user defined classed of the street that leads to the turn
 | ||||||
|  |     extractor::ClassData classes; | ||||||
|     // entry class of the turn, indicating possibility of turns
 |     // entry class of the turn, indicating possibility of turns
 | ||||||
|     util::guidance::EntryClass entry_class; |     util::guidance::EntryClass entry_class; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -140,6 +140,7 @@ void annotatePath(const FacadeT &facade, | |||||||
|         const auto name_index = facade.GetNameIndex(node_id); |         const auto name_index = facade.GetNameIndex(node_id); | ||||||
|         const auto turn_instruction = facade.GetTurnInstructionForEdgeID(turn_id); |         const auto turn_instruction = facade.GetTurnInstructionForEdgeID(turn_id); | ||||||
|         const extractor::TravelMode travel_mode = facade.GetTravelMode(node_id); |         const extractor::TravelMode travel_mode = facade.GetTravelMode(node_id); | ||||||
|  |         const auto classes = facade.GetClassData(node_id); | ||||||
| 
 | 
 | ||||||
|         const auto geometry_index = facade.GetGeometryIndex(node_id); |         const auto geometry_index = facade.GetGeometryIndex(node_id); | ||||||
|         std::vector<NodeID> id_vector; |         std::vector<NodeID> id_vector; | ||||||
| @ -186,6 +187,7 @@ void annotatePath(const FacadeT &facade, | |||||||
|                                              extractor::guidance::TurnInstruction::NO_TURN(), |                                              extractor::guidance::TurnInstruction::NO_TURN(), | ||||||
|                                              {{0, INVALID_LANEID}, INVALID_LANE_DESCRIPTIONID}, |                                              {{0, INVALID_LANEID}, INVALID_LANE_DESCRIPTIONID}, | ||||||
|                                              travel_mode, |                                              travel_mode, | ||||||
|  |                                              classes, | ||||||
|                                              EMPTY_ENTRY_CLASS, |                                              EMPTY_ENTRY_CLASS, | ||||||
|                                              datasource_vector[segment_idx], |                                              datasource_vector[segment_idx], | ||||||
|                                              util::guidance::TurnBearing(0), |                                              util::guidance::TurnBearing(0), | ||||||
| @ -261,6 +263,7 @@ void annotatePath(const FacadeT &facade, | |||||||
|                      extractor::guidance::TurnInstruction::NO_TURN(), |                      extractor::guidance::TurnInstruction::NO_TURN(), | ||||||
|                      {{0, INVALID_LANEID}, INVALID_LANE_DESCRIPTIONID}, |                      {{0, INVALID_LANEID}, INVALID_LANE_DESCRIPTIONID}, | ||||||
|                      facade.GetTravelMode(target_node_id), |                      facade.GetTravelMode(target_node_id), | ||||||
|  |                      facade.GetClassData(target_node_id), | ||||||
|                      EMPTY_ENTRY_CLASS, |                      EMPTY_ENTRY_CLASS, | ||||||
|                      datasource_vector[segment_idx], |                      datasource_vector[segment_idx], | ||||||
|                      util::guidance::TurnBearing(0), |                      util::guidance::TurnBearing(0), | ||||||
|  | |||||||
							
								
								
									
										22
									
								
								include/extractor/class_data.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								include/extractor/class_data.hpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,22 @@ | |||||||
|  | #ifndef OSRM_EXTRACTOR_CLASSES_DATA_HPP | ||||||
|  | #define OSRM_EXTRACTOR_CLASSES_DATA_HPP | ||||||
|  | 
 | ||||||
|  | #include "util/bit_range.hpp" | ||||||
|  | 
 | ||||||
|  | #include <cstdint> | ||||||
|  | 
 | ||||||
|  | namespace osrm | ||||||
|  | { | ||||||
|  | namespace extractor | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | using ClassData = std::uint8_t; | ||||||
|  | static const std::uint8_t MAX_CLASS_INDEX = 8 - 1; | ||||||
|  | 
 | ||||||
|  | inline bool isSubset(const ClassData lhs, const ClassData rhs) { return (lhs & rhs) == lhs; } | ||||||
|  | 
 | ||||||
|  | inline auto getClassIndexes(const ClassData data) { return util::makeBitRange<ClassData>(data); } | ||||||
|  | } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
| @ -85,6 +85,10 @@ struct ExtractionWay | |||||||
|     } |     } | ||||||
|     const char *GetTurnLanesBackward() const { return turn_lanes_backward.c_str(); } |     const char *GetTurnLanesBackward() const { return turn_lanes_backward.c_str(); } | ||||||
| 
 | 
 | ||||||
|  |     // markers for determining user-defined classes for each way
 | ||||||
|  |     std::unordered_map<std::string, bool> forward_classes; | ||||||
|  |     std::unordered_map<std::string, bool> backward_classes; | ||||||
|  | 
 | ||||||
|     // speed in km/h
 |     // speed in km/h
 | ||||||
|     double forward_speed; |     double forward_speed; | ||||||
|     double backward_speed; |     double backward_speed; | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| #ifndef EXTRACTOR_CALLBACKS_HPP | #ifndef EXTRACTOR_CALLBACKS_HPP | ||||||
| #define EXTRACTOR_CALLBACKS_HPP | #define EXTRACTOR_CALLBACKS_HPP | ||||||
| 
 | 
 | ||||||
|  | #include "extractor/class_data.hpp" | ||||||
| #include "extractor/guidance/turn_lane_types.hpp" | #include "extractor/guidance/turn_lane_types.hpp" | ||||||
| #include "util/typedefs.hpp" | #include "util/typedefs.hpp" | ||||||
| 
 | 
 | ||||||
| @ -61,13 +62,18 @@ class ExtractorCallbacks | |||||||
|     using MapKey = std::tuple<std::string, std::string, std::string, std::string, std::string>; |     using MapKey = std::tuple<std::string, std::string, std::string, std::string, std::string>; | ||||||
|     using MapVal = unsigned; |     using MapVal = unsigned; | ||||||
|     std::unordered_map<MapKey, MapVal> string_map; |     std::unordered_map<MapKey, MapVal> string_map; | ||||||
|     guidance::LaneDescriptionMap lane_description_map; |  | ||||||
|     ExtractionContainers &external_memory; |     ExtractionContainers &external_memory; | ||||||
|  |     std::unordered_map<std::string, ClassData> &classes_map; | ||||||
|  |     guidance::LaneDescriptionMap &lane_description_map; | ||||||
|     bool fallback_to_duration; |     bool fallback_to_duration; | ||||||
|     bool force_split_edges; |     bool force_split_edges; | ||||||
| 
 | 
 | ||||||
|   public: |   public: | ||||||
|  |     using ClassesMap = std::unordered_map<std::string, ClassData>; | ||||||
|  | 
 | ||||||
|     explicit ExtractorCallbacks(ExtractionContainers &extraction_containers, |     explicit ExtractorCallbacks(ExtractionContainers &extraction_containers, | ||||||
|  |                                 std::unordered_map<std::string, ClassData> &classes_map, | ||||||
|  |                                 guidance::LaneDescriptionMap &lane_description_map, | ||||||
|                                 const ProfileProperties &properties); |                                 const ProfileProperties &properties); | ||||||
| 
 | 
 | ||||||
|     ExtractorCallbacks(const ExtractorCallbacks &) = delete; |     ExtractorCallbacks(const ExtractorCallbacks &) = delete; | ||||||
| @ -81,9 +87,6 @@ class ExtractorCallbacks | |||||||
| 
 | 
 | ||||||
|     // warning: caller needs to take care of synchronization!
 |     // warning: caller needs to take care of synchronization!
 | ||||||
|     void ProcessWay(const osmium::Way ¤t_way, const ExtractionWay &result_way); |     void ProcessWay(const osmium::Way ¤t_way, const ExtractionWay &result_way); | ||||||
| 
 |  | ||||||
|     // destroys the internal laneDescriptionMap
 |  | ||||||
|     guidance::LaneDescriptionMap &&moveOutLaneDescriptionMap(); |  | ||||||
| }; | }; | ||||||
| } | } | ||||||
| } | } | ||||||
|  | |||||||
| @ -72,6 +72,7 @@ struct InternalExtractorEdge | |||||||
|                  false, // local access only
 |                  false, // local access only
 | ||||||
|                  false, // split edge
 |                  false, // split edge
 | ||||||
|                  TRAVEL_MODE_INACCESSIBLE, |                  TRAVEL_MODE_INACCESSIBLE, | ||||||
|  |                  0, | ||||||
|                  guidance::TurnLaneType::empty, |                  guidance::TurnLaneType::empty, | ||||||
|                  guidance::RoadClassification()), |                  guidance::RoadClassification()), | ||||||
|           weight_data(), duration_data() |           weight_data(), duration_data() | ||||||
| @ -91,6 +92,7 @@ struct InternalExtractorEdge | |||||||
|                                    bool restricted, |                                    bool restricted, | ||||||
|                                    bool is_split, |                                    bool is_split, | ||||||
|                                    TravelMode travel_mode, |                                    TravelMode travel_mode, | ||||||
|  |                                    ClassData classes, | ||||||
|                                    LaneDescriptionID lane_description, |                                    LaneDescriptionID lane_description, | ||||||
|                                    guidance::RoadClassification road_classification, |                                    guidance::RoadClassification road_classification, | ||||||
|                                    util::Coordinate source_coordinate) |                                    util::Coordinate source_coordinate) | ||||||
| @ -107,6 +109,7 @@ struct InternalExtractorEdge | |||||||
|                  restricted, |                  restricted, | ||||||
|                  is_split, |                  is_split, | ||||||
|                  travel_mode, |                  travel_mode, | ||||||
|  |                  classes, | ||||||
|                  lane_description, |                  lane_description, | ||||||
|                  std::move(road_classification)), |                  std::move(road_classification)), | ||||||
|           weight_data(std::move(weight_data)), duration_data(std::move(duration_data)), |           weight_data(std::move(weight_data)), duration_data(std::move(duration_data)), | ||||||
| @ -139,6 +142,7 @@ struct InternalExtractorEdge | |||||||
|                                      false, // local access only
 |                                      false, // local access only
 | ||||||
|                                      false, // split edge
 |                                      false, // split edge
 | ||||||
|                                      TRAVEL_MODE_INACCESSIBLE, |                                      TRAVEL_MODE_INACCESSIBLE, | ||||||
|  |                                      0, | ||||||
|                                      INVALID_LANE_DESCRIPTIONID, |                                      INVALID_LANE_DESCRIPTIONID, | ||||||
|                                      guidance::RoadClassification(), |                                      guidance::RoadClassification(), | ||||||
|                                      util::Coordinate()); |                                      util::Coordinate()); | ||||||
| @ -158,6 +162,7 @@ struct InternalExtractorEdge | |||||||
|                                      false, // local access only
 |                                      false, // local access only
 | ||||||
|                                      false, // split edge
 |                                      false, // split edge
 | ||||||
|                                      TRAVEL_MODE_INACCESSIBLE, |                                      TRAVEL_MODE_INACCESSIBLE, | ||||||
|  |                                      0, | ||||||
|                                      INVALID_LANE_DESCRIPTIONID, |                                      INVALID_LANE_DESCRIPTIONID, | ||||||
|                                      guidance::RoadClassification(), |                                      guidance::RoadClassification(), | ||||||
|                                      util::Coordinate()); |                                      util::Coordinate()); | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| #ifndef NODE_BASED_EDGE_HPP | #ifndef NODE_BASED_EDGE_HPP | ||||||
| #define NODE_BASED_EDGE_HPP | #define NODE_BASED_EDGE_HPP | ||||||
| 
 | 
 | ||||||
|  | #include "extractor/class_data.hpp" | ||||||
| #include "extractor/travel_mode.hpp" | #include "extractor/travel_mode.hpp" | ||||||
| #include "util/typedefs.hpp" | #include "util/typedefs.hpp" | ||||||
| 
 | 
 | ||||||
| @ -28,6 +29,7 @@ struct NodeBasedEdge | |||||||
|                   bool restricted, |                   bool restricted, | ||||||
|                   bool is_split, |                   bool is_split, | ||||||
|                   TravelMode travel_mode, |                   TravelMode travel_mode, | ||||||
|  |                   ClassData classes, | ||||||
|                   const LaneDescriptionID lane_description_id, |                   const LaneDescriptionID lane_description_id, | ||||||
|                   guidance::RoadClassification road_classification); |                   guidance::RoadClassification road_classification); | ||||||
| 
 | 
 | ||||||
| @ -46,6 +48,7 @@ struct NodeBasedEdge | |||||||
|     std::uint8_t restricted : 1;                      // 1
 |     std::uint8_t restricted : 1;                      // 1
 | ||||||
|     std::uint8_t is_split : 1;                        // 1
 |     std::uint8_t is_split : 1;                        // 1
 | ||||||
|     TravelMode travel_mode : 4;                       // 4
 |     TravelMode travel_mode : 4;                       // 4
 | ||||||
|  |     ClassData classes;                                // 8  1
 | ||||||
|     LaneDescriptionID lane_description_id;            // 16 2
 |     LaneDescriptionID lane_description_id;            // 16 2
 | ||||||
|     guidance::RoadClassification road_classification; // 16 2
 |     guidance::RoadClassification road_classification; // 16 2
 | ||||||
| }; | }; | ||||||
| @ -65,6 +68,7 @@ struct NodeBasedEdgeWithOSM : NodeBasedEdge | |||||||
|                          bool restricted, |                          bool restricted, | ||||||
|                          bool is_split, |                          bool is_split, | ||||||
|                          TravelMode travel_mode, |                          TravelMode travel_mode, | ||||||
|  |                          ClassData classes, | ||||||
|                          const LaneDescriptionID lane_description_id, |                          const LaneDescriptionID lane_description_id, | ||||||
|                          guidance::RoadClassification road_classification); |                          guidance::RoadClassification road_classification); | ||||||
| 
 | 
 | ||||||
| @ -95,12 +99,14 @@ inline NodeBasedEdge::NodeBasedEdge(NodeID source, | |||||||
|                                     bool restricted, |                                     bool restricted, | ||||||
|                                     bool is_split, |                                     bool is_split, | ||||||
|                                     TravelMode travel_mode, |                                     TravelMode travel_mode, | ||||||
|  |                                     ClassData classes, | ||||||
|                                     const LaneDescriptionID lane_description_id, |                                     const LaneDescriptionID lane_description_id, | ||||||
|                                     guidance::RoadClassification road_classification) |                                     guidance::RoadClassification road_classification) | ||||||
|     : source(source), target(target), name_id(name_id), weight(weight), duration(duration), |     : source(source), target(target), name_id(name_id), weight(weight), duration(duration), | ||||||
|       forward(forward), backward(backward), roundabout(roundabout), circular(circular), |       forward(forward), backward(backward), roundabout(roundabout), circular(circular), | ||||||
|       startpoint(startpoint), restricted(restricted), is_split(is_split), travel_mode(travel_mode), |       startpoint(startpoint), restricted(restricted), is_split(is_split), travel_mode(travel_mode), | ||||||
|       lane_description_id(lane_description_id), road_classification(std::move(road_classification)) |       classes(classes), lane_description_id(lane_description_id), | ||||||
|  |       road_classification(std::move(road_classification)) | ||||||
| { | { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -134,6 +140,7 @@ inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM(OSMNodeID source, | |||||||
|                                                   bool restricted, |                                                   bool restricted, | ||||||
|                                                   bool is_split, |                                                   bool is_split, | ||||||
|                                                   TravelMode travel_mode, |                                                   TravelMode travel_mode, | ||||||
|  |                                                   ClassData classes, | ||||||
|                                                   const LaneDescriptionID lane_description_id, |                                                   const LaneDescriptionID lane_description_id, | ||||||
|                                                   guidance::RoadClassification road_classification) |                                                   guidance::RoadClassification road_classification) | ||||||
|     : NodeBasedEdge(SPECIAL_NODEID, |     : NodeBasedEdge(SPECIAL_NODEID, | ||||||
| @ -149,6 +156,7 @@ inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM(OSMNodeID source, | |||||||
|                     restricted, |                     restricted, | ||||||
|                     is_split, |                     is_split, | ||||||
|                     travel_mode, |                     travel_mode, | ||||||
|  |                     classes, | ||||||
|                     lane_description_id, |                     lane_description_id, | ||||||
|                     std::move(road_classification)), |                     std::move(road_classification)), | ||||||
|       osm_source_id(std::move(source)), osm_target_id(std::move(target)) |       osm_source_id(std::move(source)), osm_target_id(std::move(target)) | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| #ifndef OSRM_EXTRACTOR_NODE_DATA_CONTAINER_HPP | #ifndef OSRM_EXTRACTOR_NODE_DATA_CONTAINER_HPP | ||||||
| #define OSRM_EXTRACTOR_NODE_DATA_CONTAINER_HPP | #define OSRM_EXTRACTOR_NODE_DATA_CONTAINER_HPP | ||||||
| 
 | 
 | ||||||
|  | #include "extractor/class_data.hpp" | ||||||
| #include "extractor/travel_mode.hpp" | #include "extractor/travel_mode.hpp" | ||||||
| 
 | 
 | ||||||
| #include "storage/io_fwd.hpp" | #include "storage/io_fwd.hpp" | ||||||
| @ -41,16 +42,18 @@ template <storage::Ownership Ownership> class EdgeBasedNodeDataContainerImpl | |||||||
|     EdgeBasedNodeDataContainerImpl() = default; |     EdgeBasedNodeDataContainerImpl() = default; | ||||||
| 
 | 
 | ||||||
|     EdgeBasedNodeDataContainerImpl(std::size_t size) |     EdgeBasedNodeDataContainerImpl(std::size_t size) | ||||||
|         : geometry_ids(size), name_ids(size), component_ids(size), travel_modes(size) |         : geometry_ids(size), name_ids(size), component_ids(size), travel_modes(size), classes(size) | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     EdgeBasedNodeDataContainerImpl(Vector<GeometryID> geometry_ids, |     EdgeBasedNodeDataContainerImpl(Vector<GeometryID> geometry_ids, | ||||||
|                                    Vector<NameID> name_ids, |                                    Vector<NameID> name_ids, | ||||||
|                                    Vector<ComponentID> component_ids, |                                    Vector<ComponentID> component_ids, | ||||||
|                                    Vector<TravelMode> travel_modes) |                                    Vector<TravelMode> travel_modes, | ||||||
|  |                                    Vector<ClassData> classes) | ||||||
|         : geometry_ids(std::move(geometry_ids)), name_ids(std::move(name_ids)), |         : geometry_ids(std::move(geometry_ids)), name_ids(std::move(name_ids)), | ||||||
|           component_ids(std::move(component_ids)), travel_modes(std::move(travel_modes)) |           component_ids(std::move(component_ids)), travel_modes(std::move(travel_modes)), | ||||||
|  |           classes(std::move(classes)) | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -62,13 +65,20 @@ template <storage::Ownership Ownership> class EdgeBasedNodeDataContainerImpl | |||||||
| 
 | 
 | ||||||
|     ComponentID GetComponentID(const NodeID node_id) const { return component_ids[node_id]; } |     ComponentID GetComponentID(const NodeID node_id) const { return component_ids[node_id]; } | ||||||
| 
 | 
 | ||||||
|  |     ClassData GetClassData(const NodeID node_id) const { return classes[node_id]; } | ||||||
|  | 
 | ||||||
|     // Used by EdgeBasedGraphFactory to fill data structure
 |     // Used by EdgeBasedGraphFactory to fill data structure
 | ||||||
|     template <typename = std::enable_if<Ownership == storage::Ownership::Container>> |     template <typename = std::enable_if<Ownership == storage::Ownership::Container>> | ||||||
|     void SetData(NodeID node_id, GeometryID geometry_id, NameID name_id, TravelMode travel_mode) |     void SetData(NodeID node_id, | ||||||
|  |                  GeometryID geometry_id, | ||||||
|  |                  NameID name_id, | ||||||
|  |                  TravelMode travel_mode, | ||||||
|  |                  ClassData class_data) | ||||||
|     { |     { | ||||||
|         geometry_ids[node_id] = geometry_id; |         geometry_ids[node_id] = geometry_id; | ||||||
|         name_ids[node_id] = name_id; |         name_ids[node_id] = name_id; | ||||||
|         travel_modes[node_id] = travel_mode; |         travel_modes[node_id] = travel_mode; | ||||||
|  |         classes[node_id] = class_data; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Used by EdgeBasedGraphFactory to fill data structure
 |     // Used by EdgeBasedGraphFactory to fill data structure
 | ||||||
| @ -91,6 +101,7 @@ template <storage::Ownership Ownership> class EdgeBasedNodeDataContainerImpl | |||||||
|         util::inplacePermutation(name_ids.begin(), name_ids.end(), permutation); |         util::inplacePermutation(name_ids.begin(), name_ids.end(), permutation); | ||||||
|         util::inplacePermutation(component_ids.begin(), component_ids.end(), permutation); |         util::inplacePermutation(component_ids.begin(), component_ids.end(), permutation); | ||||||
|         util::inplacePermutation(travel_modes.begin(), travel_modes.end(), permutation); |         util::inplacePermutation(travel_modes.begin(), travel_modes.end(), permutation); | ||||||
|  |         util::inplacePermutation(classes.begin(), classes.end(), permutation); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|   private: |   private: | ||||||
| @ -98,6 +109,7 @@ template <storage::Ownership Ownership> class EdgeBasedNodeDataContainerImpl | |||||||
|     Vector<NameID> name_ids; |     Vector<NameID> name_ids; | ||||||
|     Vector<ComponentID> component_ids; |     Vector<ComponentID> component_ids; | ||||||
|     Vector<TravelMode> travel_modes; |     Vector<TravelMode> travel_modes; | ||||||
|  |     Vector<ClassData> classes; | ||||||
| }; | }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,8 @@ | |||||||
| #ifndef PROFILE_PROPERTIES_HPP | #ifndef PROFILE_PROPERTIES_HPP | ||||||
| #define PROFILE_PROPERTIES_HPP | #define PROFILE_PROPERTIES_HPP | ||||||
| 
 | 
 | ||||||
|  | #include "extractor/class_data.hpp" | ||||||
|  | 
 | ||||||
| #include "util/typedefs.hpp" | #include "util/typedefs.hpp" | ||||||
| 
 | 
 | ||||||
| #include <algorithm> | #include <algorithm> | ||||||
| @ -17,6 +19,7 @@ const constexpr auto DEFAULT_MAX_SPEED = 180 / 3.6; // 180kmph -> m/s | |||||||
| struct ProfileProperties | struct ProfileProperties | ||||||
| { | { | ||||||
|     static constexpr int MAX_WEIGHT_NAME_LENGTH = 255; |     static constexpr int MAX_WEIGHT_NAME_LENGTH = 255; | ||||||
|  |     static constexpr int MAX_CLASS_NAME_LENGTH = 255; | ||||||
| 
 | 
 | ||||||
|     ProfileProperties() |     ProfileProperties() | ||||||
|         : traffic_signal_penalty(0), u_turn_penalty(0), |         : traffic_signal_penalty(0), u_turn_penalty(0), | ||||||
| @ -66,6 +69,22 @@ struct ProfileProperties | |||||||
|         return std::string(weight_name); |         return std::string(weight_name); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     void SetClassName(std::size_t index, const std::string &name) | ||||||
|  |     { | ||||||
|  |         char *name_ptr = class_names[index]; | ||||||
|  |         auto count = std::min<std::size_t>(name.length(), MAX_CLASS_NAME_LENGTH) + 1; | ||||||
|  |         std::copy_n(name.c_str(), count, name_ptr); | ||||||
|  |         // Make sure this is always zero terminated
 | ||||||
|  |         BOOST_ASSERT(class_names[index][count - 1] == '\0'); | ||||||
|  |         BOOST_ASSERT(class_names[index][MAX_CLASS_NAME_LENGTH] == '\0'); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     std::string GetClassName(std::size_t index) const | ||||||
|  |     { | ||||||
|  |         BOOST_ASSERT(index <= MAX_CLASS_INDEX); | ||||||
|  |         return std::string(class_names[index]); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     double GetWeightMultiplier() const { return std::pow(10., weight_precision); } |     double GetWeightMultiplier() const { return std::pow(10., weight_precision); } | ||||||
| 
 | 
 | ||||||
|     double GetMaxTurnWeight() const |     double GetMaxTurnWeight() const | ||||||
| @ -86,6 +105,8 @@ struct ProfileProperties | |||||||
|     bool fallback_to_duration; |     bool fallback_to_duration; | ||||||
|     //! stores the name of the weight (e.g. 'duration', 'distance', 'safety')
 |     //! stores the name of the weight (e.g. 'duration', 'distance', 'safety')
 | ||||||
|     char weight_name[MAX_WEIGHT_NAME_LENGTH + 1]; |     char weight_name[MAX_WEIGHT_NAME_LENGTH + 1]; | ||||||
|  |     //! stores the names of each class
 | ||||||
|  |     std::array<char[MAX_CLASS_NAME_LENGTH + 1], MAX_CLASS_INDEX + 1> class_names; | ||||||
|     unsigned weight_precision = 1; |     unsigned weight_precision = 1; | ||||||
|     bool force_split_edges = false; |     bool force_split_edges = false; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -121,6 +121,7 @@ inline void read(storage::io::FileReader &reader, | |||||||
|     storage::serialization::read(reader, node_data_container.name_ids); |     storage::serialization::read(reader, node_data_container.name_ids); | ||||||
|     storage::serialization::read(reader, node_data_container.component_ids); |     storage::serialization::read(reader, node_data_container.component_ids); | ||||||
|     storage::serialization::read(reader, node_data_container.travel_modes); |     storage::serialization::read(reader, node_data_container.travel_modes); | ||||||
|  |     storage::serialization::read(reader, node_data_container.classes); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template <storage::Ownership Ownership> | template <storage::Ownership Ownership> | ||||||
| @ -131,6 +132,7 @@ inline void write(storage::io::FileWriter &writer, | |||||||
|     storage::serialization::write(writer, node_data_container.name_ids); |     storage::serialization::write(writer, node_data_container.name_ids); | ||||||
|     storage::serialization::write(writer, node_data_container.component_ids); |     storage::serialization::write(writer, node_data_container.component_ids); | ||||||
|     storage::serialization::write(writer, node_data_container.travel_modes); |     storage::serialization::write(writer, node_data_container.travel_modes); | ||||||
|  |     storage::serialization::write(writer, node_data_container.classes); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // read/write for conditional turn restrictions file
 | // read/write for conditional turn restrictions file
 | ||||||
|  | |||||||
| @ -23,6 +23,7 @@ const constexpr char *block_id_to_name[] = {"NAME_CHAR_DATA", | |||||||
|                                             "NAME_ID_LIST", |                                             "NAME_ID_LIST", | ||||||
|                                             "COMPONENT_ID_LIST", |                                             "COMPONENT_ID_LIST", | ||||||
|                                             "TRAVEL_MODE_LIST", |                                             "TRAVEL_MODE_LIST", | ||||||
|  |                                             "CLASSES_LIST", | ||||||
|                                             "CH_GRAPH_NODE_LIST", |                                             "CH_GRAPH_NODE_LIST", | ||||||
|                                             "CH_GRAPH_EDGE_LIST", |                                             "CH_GRAPH_EDGE_LIST", | ||||||
|                                             "COORDINATE_LIST", |                                             "COORDINATE_LIST", | ||||||
| @ -79,6 +80,7 @@ struct DataLayout | |||||||
|         NAME_ID_LIST, |         NAME_ID_LIST, | ||||||
|         COMPONENT_ID_LIST, |         COMPONENT_ID_LIST, | ||||||
|         TRAVEL_MODE_LIST, |         TRAVEL_MODE_LIST, | ||||||
|  |         CLASSES_LIST, | ||||||
|         CH_GRAPH_NODE_LIST, |         CH_GRAPH_NODE_LIST, | ||||||
|         CH_GRAPH_EDGE_LIST, |         CH_GRAPH_EDGE_LIST, | ||||||
|         COORDINATE_LIST, |         COORDINATE_LIST, | ||||||
|  | |||||||
							
								
								
									
										99
									
								
								include/util/bit_range.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								include/util/bit_range.hpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,99 @@ | |||||||
|  | #ifndef OSRM_UTIL_BIT_RANGE_HPP | ||||||
|  | #define OSRM_UTIL_BIT_RANGE_HPP | ||||||
|  | 
 | ||||||
|  | #include "util/msb.hpp" | ||||||
|  | 
 | ||||||
|  | #include <boost/iterator/iterator_facade.hpp> | ||||||
|  | #include <boost/range/iterator_range.hpp> | ||||||
|  | 
 | ||||||
|  | namespace osrm | ||||||
|  | { | ||||||
|  | namespace util | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | namespace detail | ||||||
|  | { | ||||||
|  | template <typename T> std::size_t countOnes(T value) | ||||||
|  | { | ||||||
|  |     static_assert(std::is_unsigned<T>::value, "Only unsigned types allowed"); | ||||||
|  |     std::size_t number_of_ones = 0; | ||||||
|  |     while (value > 0) | ||||||
|  |     { | ||||||
|  |         auto index = msb(value); | ||||||
|  |         value = value & ~(T{1} << index); | ||||||
|  |         number_of_ones++; | ||||||
|  |     } | ||||||
|  |     return number_of_ones; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #if (defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)) | ||||||
|  | inline std::size_t countOnes(std::uint8_t value) | ||||||
|  | { | ||||||
|  |     return __builtin_popcount(std::uint32_t{value}); | ||||||
|  | } | ||||||
|  | inline std::size_t countOnes(std::uint16_t value) | ||||||
|  | { | ||||||
|  |     return __builtin_popcount(std::uint32_t{value}); | ||||||
|  | } | ||||||
|  | inline std::size_t countOnes(unsigned int value) { return __builtin_popcount(value); } | ||||||
|  | inline std::size_t countOnes(unsigned long value) { return __builtin_popcountl(value); } | ||||||
|  | inline std::size_t countOnes(unsigned long long value) { return __builtin_popcountll(value); } | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Investigate if we can replace this with
 | ||||||
|  | // http://www.boost.org/doc/libs/1_64_0/libs/dynamic_bitset/dynamic_bitset.html
 | ||||||
|  | template <typename DataT> | ||||||
|  | class BitIterator : public boost::iterator_facade<BitIterator<DataT>, | ||||||
|  |                                                   const std::size_t, | ||||||
|  |                                                   boost::forward_traversal_tag, | ||||||
|  |                                                   const std::size_t> | ||||||
|  | { | ||||||
|  |     typedef boost::iterator_facade<BitIterator<DataT>, | ||||||
|  |                                    const std::size_t, | ||||||
|  |                                    boost::forward_traversal_tag, | ||||||
|  |                                    const std::size_t> | ||||||
|  |         base_t; | ||||||
|  | 
 | ||||||
|  |   public: | ||||||
|  |     typedef typename base_t::value_type value_type; | ||||||
|  |     typedef typename base_t::difference_type difference_type; | ||||||
|  |     typedef typename base_t::reference reference; | ||||||
|  |     typedef std::random_access_iterator_tag iterator_category; | ||||||
|  | 
 | ||||||
|  |     explicit BitIterator() : m_value(0) {} | ||||||
|  |     explicit BitIterator(const DataT x) : m_value(std::move(x)) {} | ||||||
|  | 
 | ||||||
|  |   private: | ||||||
|  |     void increment() | ||||||
|  |     { | ||||||
|  |         auto index = msb(m_value); | ||||||
|  |         m_value = m_value & ~(DataT{1} << index); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     difference_type distance_to(const BitIterator &other) const | ||||||
|  |     { | ||||||
|  |         return detail::countOnes(m_value) - detail::countOnes(other.m_value); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     bool equal(const BitIterator &other) const { return m_value == other.m_value; } | ||||||
|  | 
 | ||||||
|  |     reference dereference() const | ||||||
|  |     { | ||||||
|  |         BOOST_ASSERT(m_value > 0); | ||||||
|  |         return msb(m_value); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     friend class ::boost::iterator_core_access; | ||||||
|  |     DataT m_value; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | // Returns range over all 1 bits of value
 | ||||||
|  | template <typename T> auto makeBitRange(const T value) | ||||||
|  | { | ||||||
|  |     return boost::make_iterator_range(BitIterator<T>{value}, BitIterator<T>{}); | ||||||
|  | } | ||||||
|  | } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
| @ -3,6 +3,7 @@ | |||||||
| 
 | 
 | ||||||
| #include <boost/assert.hpp> | #include <boost/assert.hpp> | ||||||
| 
 | 
 | ||||||
|  | #include <climits> | ||||||
| #include <cstdint> | #include <cstdint> | ||||||
| #include <utility> | #include <utility> | ||||||
| 
 | 
 | ||||||
| @ -26,16 +27,24 @@ template <typename T> std::size_t msb(T value) | |||||||
|     return msb - 1; |     return msb - 1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #if (defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)) && __x86_64__ | #if (defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)) | ||||||
| inline std::size_t msb(std::uint64_t v) | inline std::size_t msb(unsigned long long v) | ||||||
| { | { | ||||||
|     BOOST_ASSERT(v > 0); |     BOOST_ASSERT(v > 0); | ||||||
|     return 63UL - __builtin_clzl(v); |     constexpr auto MSB_INDEX = CHAR_BIT * sizeof(unsigned long long) - 1; | ||||||
|  |     return MSB_INDEX - __builtin_clzll(v); | ||||||
| } | } | ||||||
| inline std::size_t msb(std::uint32_t v) | inline std::size_t msb(unsigned long v) | ||||||
| { | { | ||||||
|     BOOST_ASSERT(v > 0); |     BOOST_ASSERT(v > 0); | ||||||
|     return 31UL - __builtin_clz(v); |     constexpr auto MSB_INDEX = CHAR_BIT * sizeof(unsigned long) - 1; | ||||||
|  |     return MSB_INDEX - __builtin_clzl(v); | ||||||
|  | } | ||||||
|  | inline std::size_t msb(unsigned int v) | ||||||
|  | { | ||||||
|  |     BOOST_ASSERT(v > 0); | ||||||
|  |     constexpr auto MSB_INDEX = CHAR_BIT * sizeof(unsigned int) - 1; | ||||||
|  |     return MSB_INDEX - __builtin_clz(v); | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| #ifndef NODE_BASED_GRAPH_HPP | #ifndef NODE_BASED_GRAPH_HPP | ||||||
| #define NODE_BASED_GRAPH_HPP | #define NODE_BASED_GRAPH_HPP | ||||||
| 
 | 
 | ||||||
|  | #include "extractor/class_data.hpp" | ||||||
| #include "extractor/guidance/road_classification.hpp" | #include "extractor/guidance/road_classification.hpp" | ||||||
| #include "extractor/node_based_edge.hpp" | #include "extractor/node_based_edge.hpp" | ||||||
| #include "util/dynamic_graph.hpp" | #include "util/dynamic_graph.hpp" | ||||||
| @ -35,10 +36,12 @@ struct NodeBasedEdgeData | |||||||
|                       bool startpoint, |                       bool startpoint, | ||||||
|                       bool restricted, |                       bool restricted, | ||||||
|                       extractor::TravelMode travel_mode, |                       extractor::TravelMode travel_mode, | ||||||
|  |                       extractor::ClassData classes, | ||||||
|                       const LaneDescriptionID lane_description_id) |                       const LaneDescriptionID lane_description_id) | ||||||
|         : weight(weight), duration(duration), edge_id(edge_id), name_id(name_id), |         : weight(weight), duration(duration), edge_id(edge_id), name_id(name_id), | ||||||
|           reversed(reversed), roundabout(roundabout), circular(circular), startpoint(startpoint), |           reversed(reversed), roundabout(roundabout), circular(circular), startpoint(startpoint), | ||||||
|           restricted(restricted), travel_mode(travel_mode), lane_description_id(lane_description_id) |           restricted(restricted), travel_mode(travel_mode), classes(classes), | ||||||
|  |           lane_description_id(lane_description_id) | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -52,6 +55,7 @@ struct NodeBasedEdgeData | |||||||
|     bool startpoint : 1; |     bool startpoint : 1; | ||||||
|     bool restricted : 1; |     bool restricted : 1; | ||||||
|     extractor::TravelMode travel_mode : 4; |     extractor::TravelMode travel_mode : 4; | ||||||
|  |     extractor::ClassData classes; | ||||||
|     LaneDescriptionID lane_description_id; |     LaneDescriptionID lane_description_id; | ||||||
|     extractor::guidance::RoadClassification road_classification; |     extractor::guidance::RoadClassification road_classification; | ||||||
| 
 | 
 | ||||||
| @ -59,7 +63,7 @@ struct NodeBasedEdgeData | |||||||
|     { |     { | ||||||
|         return (reversed == other.reversed) && (roundabout == other.roundabout) && |         return (reversed == other.reversed) && (roundabout == other.roundabout) && | ||||||
|                (circular == other.circular) && (startpoint == other.startpoint) && |                (circular == other.circular) && (startpoint == other.startpoint) && | ||||||
|                (travel_mode == other.travel_mode) && |                (travel_mode == other.travel_mode) && (classes == other.classes) && | ||||||
|                (road_classification == other.road_classification) && |                (road_classification == other.road_classification) && | ||||||
|                (restricted == other.restricted); |                (restricted == other.restricted); | ||||||
|     } |     } | ||||||
| @ -89,6 +93,7 @@ NodeBasedDynamicGraphFromEdges(NodeID number_of_nodes, | |||||||
|             output_edge.data.circular = input_edge.circular; |             output_edge.data.circular = input_edge.circular; | ||||||
|             output_edge.data.name_id = input_edge.name_id; |             output_edge.data.name_id = input_edge.name_id; | ||||||
|             output_edge.data.travel_mode = input_edge.travel_mode; |             output_edge.data.travel_mode = input_edge.travel_mode; | ||||||
|  |             output_edge.data.classes = input_edge.classes; | ||||||
|             output_edge.data.startpoint = input_edge.startpoint; |             output_edge.data.startpoint = input_edge.startpoint; | ||||||
|             output_edge.data.restricted = input_edge.restricted; |             output_edge.data.restricted = input_edge.restricted; | ||||||
|             output_edge.data.road_classification = input_edge.road_classification; |             output_edge.data.road_classification = input_edge.road_classification; | ||||||
|  | |||||||
| @ -366,6 +366,9 @@ function way_function(way, result) | |||||||
|     'handle_maxspeed', |     'handle_maxspeed', | ||||||
|     'handle_penalties', |     'handle_penalties', | ||||||
| 
 | 
 | ||||||
|  |     -- compute class labels | ||||||
|  |     'handle_classes', | ||||||
|  | 
 | ||||||
|     -- handle turn lanes and road classification, used for guidance |     -- handle turn lanes and road classification, used for guidance | ||||||
|     'handle_turn_lanes', |     'handle_turn_lanes', | ||||||
|     'handle_classification', |     'handle_classification', | ||||||
|  | |||||||
| @ -277,6 +277,38 @@ function Handlers.handle_speed(way,result,data,profile) | |||||||
|   end |   end | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
|  | -- add class information | ||||||
|  | function Handlers.handle_classes(way,result,data,profile) | ||||||
|  |     local forward_toll, backward_toll = Tags.get_forward_backward_by_key(way, data, "toll") | ||||||
|  |     local forward_route, backward_route = Tags.get_forward_backward_by_key(way, data, "route") | ||||||
|  | 
 | ||||||
|  |     if forward_toll == "yes" then | ||||||
|  |         result.forward_classes["toll"] = true | ||||||
|  |     end | ||||||
|  |     if backward_toll == "yes" then | ||||||
|  |         result.backward_classes["toll"] = true | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     if forward_route == "ferry" then | ||||||
|  |         result.forward_classes["ferry"] = true | ||||||
|  |     end | ||||||
|  |     if backward_route == "ferry" then | ||||||
|  |         result.backward_classes["ferry"] = true | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     if result.forward_restricted then | ||||||
|  |         result.forward_classes["restricted"] = true | ||||||
|  |     end | ||||||
|  |     if result.backward_restricted then | ||||||
|  |         result.backward_classes["restricted"] = true | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     if data.highway == "motorway" or data.highway == "motorway_link" then | ||||||
|  |         result.forward_classes["motorway"] = true | ||||||
|  |         result.backward_classes["motorway"] = true | ||||||
|  |     end | ||||||
|  | end | ||||||
|  | 
 | ||||||
| -- reduce speed on bad surfaces | -- reduce speed on bad surfaces | ||||||
| function Handlers.handle_surface(way,result,data,profile) | function Handlers.handle_surface(way,result,data,profile) | ||||||
|   local surface = way:get_value_by_key("surface") |   local surface = way:get_value_by_key("surface") | ||||||
|  | |||||||
| @ -265,6 +265,18 @@ util::json::Object makeRouteStep(guidance::RouteStep step, util::json::Value geo | |||||||
|     route_step.values["maneuver"] = makeStepManeuver(std::move(step.maneuver)); |     route_step.values["maneuver"] = makeStepManeuver(std::move(step.maneuver)); | ||||||
|     route_step.values["geometry"] = std::move(geometry); |     route_step.values["geometry"] = std::move(geometry); | ||||||
| 
 | 
 | ||||||
|  |     if (!step.classes.empty()) | ||||||
|  |     { | ||||||
|  |         util::json::Array classes; | ||||||
|  |         classes.values.reserve(step.classes.size()); | ||||||
|  |         std::transform( | ||||||
|  |             step.classes.begin(), | ||||||
|  |             step.classes.end(), | ||||||
|  |             std::back_inserter(classes.values), | ||||||
|  |             [](const std::string &class_name) { return util::json::String{class_name}; }); | ||||||
|  |         route_step.values["classes"] = std::move(classes); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     util::json::Array intersections; |     util::json::Array intersections; | ||||||
|     intersections.values.reserve(step.intersections.size()); |     intersections.values.reserve(step.intersections.size()); | ||||||
|     std::transform(step.intersections.begin(), |     std::transform(step.intersections.begin(), | ||||||
|  | |||||||
| @ -486,6 +486,7 @@ void trimShortSegments(std::vector<RouteStep> &steps, LegGeometry &geometry) | |||||||
|         auto &new_next_to_last = *(steps.end() - 2); |         auto &new_next_to_last = *(steps.end() - 2); | ||||||
|         next_to_last_step.AdaptStepSignage(new_next_to_last); |         next_to_last_step.AdaptStepSignage(new_next_to_last); | ||||||
|         next_to_last_step.mode = new_next_to_last.mode; |         next_to_last_step.mode = new_next_to_last.mode; | ||||||
|  |         next_to_last_step.classes = new_next_to_last.classes; | ||||||
|         // the geometry indices of the last step are already correct;
 |         // the geometry indices of the last step are already correct;
 | ||||||
|     } |     } | ||||||
|     else if (util::coordinate_calculation::haversineDistance( |     else if (util::coordinate_calculation::haversineDistance( | ||||||
|  | |||||||
| @ -148,13 +148,15 @@ NBGToEBG EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const N | |||||||
|     m_edge_based_node_container.SetData(forward_data.edge_id, |     m_edge_based_node_container.SetData(forward_data.edge_id, | ||||||
|                                         GeometryID{packed_geometry_id, true}, |                                         GeometryID{packed_geometry_id, true}, | ||||||
|                                         forward_data.name_id, |                                         forward_data.name_id, | ||||||
|                                         forward_data.travel_mode); |                                         forward_data.travel_mode, | ||||||
|  |                                         forward_data.classes); | ||||||
|     if (reverse_data.edge_id != SPECIAL_EDGEID) |     if (reverse_data.edge_id != SPECIAL_EDGEID) | ||||||
|     { |     { | ||||||
|         m_edge_based_node_container.SetData(reverse_data.edge_id, |         m_edge_based_node_container.SetData(reverse_data.edge_id, | ||||||
|                                             GeometryID{packed_geometry_id, false}, |                                             GeometryID{packed_geometry_id, false}, | ||||||
|                                             reverse_data.name_id, |                                             reverse_data.name_id, | ||||||
|                                             reverse_data.travel_mode); |                                             reverse_data.travel_mode, | ||||||
|  |                                             reverse_data.classes); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Add segments of edge-based nodes
 |     // Add segments of edge-based nodes
 | ||||||
|  | |||||||
| @ -63,6 +63,21 @@ namespace osrm | |||||||
| namespace extractor | namespace extractor | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
|  | namespace | ||||||
|  | { | ||||||
|  | // Converts the class name map into a fixed mapping of index to name
 | ||||||
|  | void SetClassNames(const ExtractorCallbacks::ClassesMap &classes_map, | ||||||
|  |                    ProfileProperties &profile_properties) | ||||||
|  | { | ||||||
|  |     for (const auto &pair : classes_map) | ||||||
|  |     { | ||||||
|  |         auto range = getClassIndexes(pair.second); | ||||||
|  |         BOOST_ASSERT(range.size() == 1); | ||||||
|  |         profile_properties.SetClassName(range.front(), pair.first); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * TODO: Refactor this function into smaller functions for better readability. |  * TODO: Refactor this function into smaller functions for better readability. | ||||||
|  * |  * | ||||||
| @ -201,8 +216,13 @@ Extractor::ParseOSMData(ScriptingEnvironment &scripting_environment, | |||||||
|     TIMER_START(parsing); |     TIMER_START(parsing); | ||||||
| 
 | 
 | ||||||
|     ExtractionContainers extraction_containers; |     ExtractionContainers extraction_containers; | ||||||
|     auto extractor_callbacks = std::make_unique<ExtractorCallbacks>( |     ExtractorCallbacks::ClassesMap classes_map; | ||||||
|         extraction_containers, scripting_environment.GetProfileProperties()); |     guidance::LaneDescriptionMap turn_lane_map; | ||||||
|  |     auto extractor_callbacks = | ||||||
|  |         std::make_unique<ExtractorCallbacks>(extraction_containers, | ||||||
|  |                                              classes_map, | ||||||
|  |                                              turn_lane_map, | ||||||
|  |                                              scripting_environment.GetProfileProperties()); | ||||||
| 
 | 
 | ||||||
|     // setup raster sources
 |     // setup raster sources
 | ||||||
|     scripting_environment.SetupSources(); |     scripting_environment.SetupSources(); | ||||||
| @ -304,10 +324,6 @@ Extractor::ParseOSMData(ScriptingEnvironment &scripting_environment, | |||||||
|     util::Log() << "Raw input contains " << number_of_nodes << " nodes, " << number_of_ways |     util::Log() << "Raw input contains " << number_of_nodes << " nodes, " << number_of_ways | ||||||
|                 << " ways, and " << number_of_relations << " relations"; |                 << " ways, and " << number_of_relations << " relations"; | ||||||
| 
 | 
 | ||||||
|     // take control over the turn lane map
 |  | ||||||
|     guidance::LaneDescriptionMap turn_lane_map; |  | ||||||
|     turn_lane_map.data = extractor_callbacks->moveOutLaneDescriptionMap().data; |  | ||||||
| 
 |  | ||||||
|     extractor_callbacks.reset(); |     extractor_callbacks.reset(); | ||||||
| 
 | 
 | ||||||
|     if (extraction_containers.all_edges_list.empty()) |     if (extraction_containers.all_edges_list.empty()) | ||||||
| @ -321,8 +337,9 @@ Extractor::ParseOSMData(ScriptingEnvironment &scripting_environment, | |||||||
|                                       config.restriction_file_name, |                                       config.restriction_file_name, | ||||||
|                                       config.names_file_name); |                                       config.names_file_name); | ||||||
| 
 | 
 | ||||||
|     files::writeProfileProperties(config.profile_properties_output_path, |     auto profile_properties = scripting_environment.GetProfileProperties(); | ||||||
|                                   scripting_environment.GetProfileProperties()); |     SetClassNames(classes_map, profile_properties); | ||||||
|  |     files::writeProfileProperties(config.profile_properties_output_path, profile_properties); | ||||||
| 
 | 
 | ||||||
|     TIMER_STOP(extracting); |     TIMER_STOP(extracting); | ||||||
|     util::Log() << "extraction finished after " << TIMER_SEC(extracting) << "s"; |     util::Log() << "extraction finished after " << TIMER_SEC(extracting) << "s"; | ||||||
|  | |||||||
| @ -34,8 +34,11 @@ using TurnLaneDescription = guidance::TurnLaneDescription; | |||||||
| namespace TurnLaneType = guidance::TurnLaneType; | namespace TurnLaneType = guidance::TurnLaneType; | ||||||
| 
 | 
 | ||||||
| ExtractorCallbacks::ExtractorCallbacks(ExtractionContainers &extraction_containers_, | ExtractorCallbacks::ExtractorCallbacks(ExtractionContainers &extraction_containers_, | ||||||
|  |                                        std::unordered_map<std::string, ClassData> &classes_map, | ||||||
|  |                                        guidance::LaneDescriptionMap &lane_description_map, | ||||||
|                                        const ProfileProperties &properties) |                                        const ProfileProperties &properties) | ||||||
|     : external_memory(extraction_containers_), |     : external_memory(extraction_containers_), classes_map(classes_map), | ||||||
|  |       lane_description_map(lane_description_map), | ||||||
|       fallback_to_duration(properties.fallback_to_duration), |       fallback_to_duration(properties.fallback_to_duration), | ||||||
|       force_split_edges(properties.force_split_edges) |       force_split_edges(properties.force_split_edges) | ||||||
| { | { | ||||||
| @ -175,6 +178,38 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     const auto classStringToMask = [this](const std::string &class_name) { | ||||||
|  |         auto iter = classes_map.find(class_name); | ||||||
|  |         if (iter == classes_map.end()) | ||||||
|  |         { | ||||||
|  |             if (classes_map.size() > MAX_CLASS_INDEX) | ||||||
|  |             { | ||||||
|  |                 throw util::exception("Maximum number of classes if " + | ||||||
|  |                                       std::to_string(MAX_CLASS_INDEX + 1)); | ||||||
|  |             } | ||||||
|  |             ClassData class_mask = 1u << classes_map.size(); | ||||||
|  |             classes_map[class_name] = class_mask; | ||||||
|  |             return class_mask; | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             return iter->second; | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  |     const auto classesToMask = [&](const auto &classes) { | ||||||
|  |         ClassData mask = 0; | ||||||
|  |         for (const auto &name_and_flag : classes) | ||||||
|  |         { | ||||||
|  |             if (name_and_flag.second) | ||||||
|  |             { | ||||||
|  |                 mask |= classStringToMask(name_and_flag.first); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return mask; | ||||||
|  |     }; | ||||||
|  |     const ClassData forward_classes = classesToMask(parsed_way.forward_classes); | ||||||
|  |     const ClassData backward_classes = classesToMask(parsed_way.backward_classes); | ||||||
|  | 
 | ||||||
|     const auto laneStringToDescription = [](const std::string &lane_string) -> TurnLaneDescription { |     const auto laneStringToDescription = [](const std::string &lane_string) -> TurnLaneDescription { | ||||||
|         if (lane_string.empty()) |         if (lane_string.empty()) | ||||||
|             return {}; |             return {}; | ||||||
| @ -330,7 +365,7 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti | |||||||
|         (force_split_edges || (parsed_way.forward_rate != parsed_way.backward_rate) || |         (force_split_edges || (parsed_way.forward_rate != parsed_way.backward_rate) || | ||||||
|          (parsed_way.forward_speed != parsed_way.backward_speed) || |          (parsed_way.forward_speed != parsed_way.backward_speed) || | ||||||
|          (parsed_way.forward_travel_mode != parsed_way.backward_travel_mode) || |          (parsed_way.forward_travel_mode != parsed_way.backward_travel_mode) || | ||||||
|          (turn_lane_id_forward != turn_lane_id_backward)); |          (turn_lane_id_forward != turn_lane_id_backward) || (forward_classes != backward_classes)); | ||||||
| 
 | 
 | ||||||
|     if (in_forward_direction) |     if (in_forward_direction) | ||||||
|     { // add (forward) segments or (forward,backward) for non-split edges in backward direction
 |     { // add (forward) segments or (forward,backward) for non-split edges in backward direction
 | ||||||
| @ -352,6 +387,7 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti | |||||||
|                                           parsed_way.forward_restricted, |                                           parsed_way.forward_restricted, | ||||||
|                                           split_edge, |                                           split_edge, | ||||||
|                                           parsed_way.forward_travel_mode, |                                           parsed_way.forward_travel_mode, | ||||||
|  |                                           forward_classes, | ||||||
|                                           turn_lane_id_forward, |                                           turn_lane_id_forward, | ||||||
|                                           road_classification, |                                           road_classification, | ||||||
|                                           {})); |                                           {})); | ||||||
| @ -378,6 +414,7 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti | |||||||
|                                           parsed_way.backward_restricted, |                                           parsed_way.backward_restricted, | ||||||
|                                           split_edge, |                                           split_edge, | ||||||
|                                           parsed_way.backward_travel_mode, |                                           parsed_way.backward_travel_mode, | ||||||
|  |                                           backward_classes, | ||||||
|                                           turn_lane_id_backward, |                                           turn_lane_id_backward, | ||||||
|                                           road_classification, |                                           road_classification, | ||||||
|                                           {})); |                                           {})); | ||||||
| @ -399,9 +436,5 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti | |||||||
|          OSMNodeID{static_cast<std::uint64_t>(nodes.back().ref())}}); |          OSMNodeID{static_cast<std::uint64_t>(nodes.back().ref())}}); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| guidance::LaneDescriptionMap &&ExtractorCallbacks::moveOutLaneDescriptionMap() |  | ||||||
| { |  | ||||||
|     return std::move(lane_description_map); |  | ||||||
| } |  | ||||||
| } // namespace extractor
 | } // namespace extractor
 | ||||||
| } // namespace osrm
 | } // namespace osrm
 | ||||||
|  | |||||||
| @ -75,9 +75,6 @@ TurnInstruction IntersectionHandler::getInstructionForObvious(const std::size_t | |||||||
|                                                               const ConnectedRoad &road) const |                                                               const ConnectedRoad &road) const | ||||||
| { | { | ||||||
|     const auto type = findBasicTurnType(via_edge, road); |     const auto type = findBasicTurnType(via_edge, road); | ||||||
|     // handle travel modes:
 |  | ||||||
|     const auto in_mode = node_based_graph.GetEdgeData(via_edge).travel_mode; |  | ||||||
|     const auto out_mode = node_based_graph.GetEdgeData(road.eid).travel_mode; |  | ||||||
|     if (type == TurnType::OnRamp) |     if (type == TurnType::OnRamp) | ||||||
|     { |     { | ||||||
|         return {TurnType::OnRamp, getTurnDirection(road.angle)}; |         return {TurnType::OnRamp, getTurnDirection(road.angle)}; | ||||||
| @ -87,6 +84,15 @@ TurnInstruction IntersectionHandler::getInstructionForObvious(const std::size_t | |||||||
|     { |     { | ||||||
|         return {TurnType::Continue, DirectionModifier::UTurn}; |         return {TurnType::Continue, DirectionModifier::UTurn}; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     // handle travel modes:
 | ||||||
|  |     const auto in_mode = node_based_graph.GetEdgeData(via_edge).travel_mode; | ||||||
|  |     const auto out_mode = node_based_graph.GetEdgeData(road.eid).travel_mode; | ||||||
|  |     const auto in_classes = node_based_graph.GetEdgeData(via_edge).classes; | ||||||
|  |     const auto out_classes = node_based_graph.GetEdgeData(road.eid).classes; | ||||||
|  |     // if we just lose class flags we don't want to notify
 | ||||||
|  |     const auto needs_notification = in_mode != out_mode || !isSubset(out_classes, in_classes); | ||||||
|  | 
 | ||||||
|     if (type == TurnType::Turn) |     if (type == TurnType::Turn) | ||||||
|     { |     { | ||||||
|         const auto &in_data = node_based_graph.GetEdgeData(via_edge); |         const auto &in_data = node_based_graph.GetEdgeData(via_edge); | ||||||
| @ -141,14 +147,14 @@ TurnInstruction IntersectionHandler::getInstructionForObvious(const std::size_t | |||||||
|             } |             } | ||||||
|             else |             else | ||||||
|             { |             { | ||||||
|                 return {in_mode == out_mode ? TurnType::NewName : TurnType::Notification, |                 return {needs_notification ? TurnType::Notification : TurnType::NewName, | ||||||
|                         getTurnDirection(road.angle)}; |                         getTurnDirection(road.angle)}; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         // name has not changed, suppress a turn here or indicate mode change
 |         // name has not changed, suppress a turn here or indicate mode change
 | ||||||
|         else |         else | ||||||
|         { |         { | ||||||
|             if (in_mode != out_mode) |             if (needs_notification) | ||||||
|                 return {TurnType::Notification, getTurnDirection(road.angle)}; |                 return {TurnType::Notification, getTurnDirection(road.angle)}; | ||||||
|             else |             else | ||||||
|                 return {num_roads == 2 ? TurnType::NoTurn : TurnType::Suppressed, |                 return {num_roads == 2 ? TurnType::NoTurn : TurnType::Suppressed, | ||||||
| @ -156,7 +162,7 @@ TurnInstruction IntersectionHandler::getInstructionForObvious(const std::size_t | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     BOOST_ASSERT(type == TurnType::Continue); |     BOOST_ASSERT(type == TurnType::Continue); | ||||||
|     if (in_mode != out_mode) |     if (needs_notification) | ||||||
|     { |     { | ||||||
|         return {TurnType::Notification, getTurnDirection(road.angle)}; |         return {TurnType::Notification, getTurnDirection(road.angle)}; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -342,6 +342,10 @@ void Sol2ScriptingEnvironment::InitContext(LuaScriptingContext &context) | |||||||
|         &ExtractionWay::weight, |         &ExtractionWay::weight, | ||||||
|         "road_classification", |         "road_classification", | ||||||
|         &ExtractionWay::road_classification, |         &ExtractionWay::road_classification, | ||||||
|  |         "forward_classes", | ||||||
|  |         &ExtractionWay::forward_classes, | ||||||
|  |         "backward_classes", | ||||||
|  |         &ExtractionWay::backward_classes, | ||||||
|         "forward_mode", |         "forward_mode", | ||||||
|         sol::property([](const ExtractionWay &way) { return way.forward_travel_mode; }, |         sol::property([](const ExtractionWay &way) { return way.forward_travel_mode; }, | ||||||
|                       [](ExtractionWay &way, TravelMode mode) { way.forward_travel_mode = mode; }), |                       [](ExtractionWay &way, TravelMode mode) { way.forward_travel_mode = mode; }), | ||||||
|  | |||||||
| @ -11,6 +11,7 @@ | |||||||
| 
 | 
 | ||||||
| #include "customizer/edge_based_graph.hpp" | #include "customizer/edge_based_graph.hpp" | ||||||
| 
 | 
 | ||||||
|  | #include "extractor/class_data.hpp" | ||||||
| #include "extractor/compressed_edge_container.hpp" | #include "extractor/compressed_edge_container.hpp" | ||||||
| #include "extractor/edge_based_edge.hpp" | #include "extractor/edge_based_edge.hpp" | ||||||
| #include "extractor/files.hpp" | #include "extractor/files.hpp" | ||||||
| @ -253,6 +254,7 @@ void Storage::PopulateLayout(DataLayout &layout) | |||||||
|         layout.SetBlockSize<NameID>(DataLayout::NAME_ID_LIST, nodes_number); |         layout.SetBlockSize<NameID>(DataLayout::NAME_ID_LIST, nodes_number); | ||||||
|         layout.SetBlockSize<ComponentID>(DataLayout::COMPONENT_ID_LIST, nodes_number); |         layout.SetBlockSize<ComponentID>(DataLayout::COMPONENT_ID_LIST, nodes_number); | ||||||
|         layout.SetBlockSize<extractor::TravelMode>(DataLayout::TRAVEL_MODE_LIST, nodes_number); |         layout.SetBlockSize<extractor::TravelMode>(DataLayout::TRAVEL_MODE_LIST, nodes_number); | ||||||
|  |         layout.SetBlockSize<extractor::ClassData>(DataLayout::CLASSES_LIST, nodes_number); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (boost::filesystem::exists(config.hsgr_data_path)) |     if (boost::filesystem::exists(config.hsgr_data_path)) | ||||||
| @ -614,10 +616,16 @@ void Storage::PopulateData(const DataLayout &layout, char *memory_ptr) | |||||||
|         util::vector_view<extractor::TravelMode> travel_modes( |         util::vector_view<extractor::TravelMode> travel_modes( | ||||||
|             travel_mode_list_ptr, layout.num_entries[storage::DataLayout::TRAVEL_MODE_LIST]); |             travel_mode_list_ptr, layout.num_entries[storage::DataLayout::TRAVEL_MODE_LIST]); | ||||||
| 
 | 
 | ||||||
|  |         auto classes_list_ptr = layout.GetBlockPtr<extractor::ClassData, true>( | ||||||
|  |             memory_ptr, storage::DataLayout::CLASSES_LIST); | ||||||
|  |         util::vector_view<extractor::ClassData> classes( | ||||||
|  |             classes_list_ptr, layout.num_entries[storage::DataLayout::CLASSES_LIST]); | ||||||
|  | 
 | ||||||
|         extractor::EdgeBasedNodeDataView node_data(std::move(geometry_ids), |         extractor::EdgeBasedNodeDataView node_data(std::move(geometry_ids), | ||||||
|                                                    std::move(name_ids), |                                                    std::move(name_ids), | ||||||
|                                                    std::move(component_ids), |                                                    std::move(component_ids), | ||||||
|                                                    std::move(travel_modes)); |                                                    std::move(travel_modes), | ||||||
|  |                                                    std::move(classes)); | ||||||
| 
 | 
 | ||||||
|         extractor::files::readNodeData(config.edge_based_nodes_data_path, node_data); |         extractor::files::readNodeData(config.edge_based_nodes_data_path, node_data); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -53,7 +53,8 @@ BOOST_AUTO_TEST_CASE(trim_short_segments) | |||||||
|                                       0}, |                                       0}, | ||||||
|                                      0, |                                      0, | ||||||
|                                      3, |                                      3, | ||||||
|                                      {intersection1}}, |                                      {intersection1}, | ||||||
|  |                                      {}}, | ||||||
|                                     {324, |                                     {324, | ||||||
|                                      "Central Park West", |                                      "Central Park West", | ||||||
|                                      "", |                                      "", | ||||||
| @ -74,7 +75,8 @@ BOOST_AUTO_TEST_CASE(trim_short_segments) | |||||||
|                                       0}, |                                       0}, | ||||||
|                                      2, |                                      2, | ||||||
|                                      3, |                                      3, | ||||||
|                                      {intersection2}}}; |                                      {intersection2}, | ||||||
|  |                                      {}}}; | ||||||
| 
 | 
 | ||||||
|     LegGeometry geometry; |     LegGeometry geometry; | ||||||
|     geometry.locations = {{FloatLongitude{-73.981492}, FloatLatitude{40.768258}}, |     geometry.locations = {{FloatLongitude{-73.981492}, FloatLatitude{40.768258}}, | ||||||
|  | |||||||
| @ -36,6 +36,7 @@ inline InputEdge MakeUnitEdge(const NodeID from, const NodeID to) | |||||||
|             false, |             false, | ||||||
|             true, |             true, | ||||||
|             TRAVEL_MODE_INACCESSIBLE, |             TRAVEL_MODE_INACCESSIBLE, | ||||||
|  |             0, | ||||||
|             INVALID_LANE_DESCRIPTIONID}; |             INVALID_LANE_DESCRIPTIONID}; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -4,11 +4,15 @@ | |||||||
| // implements all data storage when shared memory _IS_ used
 | // implements all data storage when shared memory _IS_ used
 | ||||||
| 
 | 
 | ||||||
| #include "contractor/query_edge.hpp" | #include "contractor/query_edge.hpp" | ||||||
|  | #include "extractor/class_data.hpp" | ||||||
| #include "extractor/guidance/turn_instruction.hpp" | #include "extractor/guidance/turn_instruction.hpp" | ||||||
| #include "extractor/guidance/turn_lane_types.hpp" | #include "extractor/guidance/turn_lane_types.hpp" | ||||||
|  | #include "extractor/travel_mode.hpp" | ||||||
|  | 
 | ||||||
| #include "engine/algorithm.hpp" | #include "engine/algorithm.hpp" | ||||||
| #include "engine/datafacade/algorithm_datafacade.hpp" | #include "engine/datafacade/algorithm_datafacade.hpp" | ||||||
| #include "engine/datafacade/datafacade_base.hpp" | #include "engine/datafacade/datafacade_base.hpp" | ||||||
|  | 
 | ||||||
| #include "util/guidance/bearing_class.hpp" | #include "util/guidance/bearing_class.hpp" | ||||||
| #include "util/guidance/entry_class.hpp" | #include "util/guidance/entry_class.hpp" | ||||||
| #include "util/guidance/turn_bearing.hpp" | #include "util/guidance/turn_bearing.hpp" | ||||||
| @ -195,6 +199,14 @@ class MockBaseDataFacade : public engine::datafacade::BaseDataFacade | |||||||
|     { |     { | ||||||
|         return TRAVEL_MODE_INACCESSIBLE; |         return TRAVEL_MODE_INACCESSIBLE; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     extractor::ClassData GetClassData(const NodeID /*id*/) const override final { return 0; } | ||||||
|  | 
 | ||||||
|  |     std::vector<std::string> GetClasses(const extractor::ClassData /*data*/) const override final | ||||||
|  |     { | ||||||
|  |         return {}; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     NameID GetNameIndex(const NodeID /* id */) const override { return 0; } |     NameID GetNameIndex(const NodeID /* id */) const override { return 0; } | ||||||
| 
 | 
 | ||||||
|     StringView GetNameForID(const NameID) const override final { return {}; } |     StringView GetNameForID(const NameID) const override final { return {}; } | ||||||
|  | |||||||
							
								
								
									
										73
									
								
								unit_tests/util/bit_range.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								unit_tests/util/bit_range.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,73 @@ | |||||||
|  | #include "util/bit_range.hpp" | ||||||
|  | 
 | ||||||
|  | #include "../common/range_tools.hpp" | ||||||
|  | 
 | ||||||
|  | #include <boost/test/test_case_template.hpp> | ||||||
|  | #include <boost/test/unit_test.hpp> | ||||||
|  | 
 | ||||||
|  | BOOST_AUTO_TEST_SUITE(bit_range_test) | ||||||
|  | 
 | ||||||
|  | using namespace osrm; | ||||||
|  | using namespace osrm::util; | ||||||
|  | 
 | ||||||
|  | BOOST_AUTO_TEST_CASE(bit_range_8bit_test) | ||||||
|  | { | ||||||
|  |     std::uint8_t value_1 = (1UL << 0) | (1UL << 1) | (1UL << 5) | (1UL << 7); | ||||||
|  |     std::uint8_t value_2 = (1UL << 0); | ||||||
|  |     std::uint8_t value_3 = | ||||||
|  |         (1UL << 0) | (1UL << 1) | (1UL << 2) | (1UL << 3) | (1UL << 4) | (1UL << 5); | ||||||
|  | 
 | ||||||
|  |     CHECK_EQUAL_RANGE(makeBitRange<std::uint8_t>(value_1), 7, 5, 1, 0); | ||||||
|  |     CHECK_EQUAL_RANGE(makeBitRange<std::uint8_t>(value_2), 0); | ||||||
|  |     CHECK_EQUAL_RANGE(makeBitRange<std::uint8_t>(value_3), 5, 4, 3, 2, 1, 0); | ||||||
|  | 
 | ||||||
|  |     BOOST_CHECK_EQUAL(makeBitRange<std::uint8_t>(value_3).size(), 6); | ||||||
|  |     BOOST_CHECK_EQUAL(makeBitRange<std::uint8_t>(0).size(), 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | BOOST_AUTO_TEST_CASE(bit_range_16bit_test) | ||||||
|  | { | ||||||
|  |     std::uint16_t value_1 = (1UL << 0) | (1UL << 1) | (1UL << 9) | (1UL << 15); | ||||||
|  |     std::uint16_t value_2 = (1UL << 0); | ||||||
|  |     std::uint16_t value_3 = | ||||||
|  |         (1UL << 0) | (1UL << 1) | (1UL << 2) | (1UL << 3) | (1UL << 4) | (1UL << 5); | ||||||
|  | 
 | ||||||
|  |     CHECK_EQUAL_RANGE(makeBitRange<std::uint16_t>(value_1), 15, 9, 1, 0); | ||||||
|  |     CHECK_EQUAL_RANGE(makeBitRange<std::uint16_t>(value_2), 0); | ||||||
|  |     CHECK_EQUAL_RANGE(makeBitRange<std::uint16_t>(value_3), 5, 4, 3, 2, 1, 0); | ||||||
|  | 
 | ||||||
|  |     BOOST_CHECK_EQUAL(makeBitRange<std::uint16_t>(value_3).size(), 6); | ||||||
|  |     BOOST_CHECK_EQUAL(makeBitRange<std::uint16_t>(0).size(), 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | BOOST_AUTO_TEST_CASE(bit_range_32bit_test) | ||||||
|  | { | ||||||
|  |     std::uint32_t value_1 = (1UL << 0) | (1UL << 1) | (1UL << 17) | (1UL << 31); | ||||||
|  |     std::uint32_t value_2 = (1UL << 0); | ||||||
|  |     std::uint32_t value_3 = | ||||||
|  |         (1UL << 0) | (1UL << 1) | (1UL << 2) | (1UL << 3) | (1UL << 4) | (1UL << 5); | ||||||
|  | 
 | ||||||
|  |     CHECK_EQUAL_RANGE(makeBitRange<std::uint32_t>(value_1), 31, 17, 1, 0); | ||||||
|  |     CHECK_EQUAL_RANGE(makeBitRange<std::uint32_t>(value_2), 0); | ||||||
|  |     CHECK_EQUAL_RANGE(makeBitRange<std::uint32_t>(value_3), 5, 4, 3, 2, 1, 0); | ||||||
|  | 
 | ||||||
|  |     BOOST_CHECK_EQUAL(makeBitRange<std::uint32_t>(value_3).size(), 6); | ||||||
|  |     BOOST_CHECK_EQUAL(makeBitRange<std::uint32_t>(0).size(), 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | BOOST_AUTO_TEST_CASE(bit_range_64bit_test) | ||||||
|  | { | ||||||
|  |     std::uint64_t value_1 = (1ULL << 0) | (1ULL << 1) | (1ULL << 33) | (1ULL << 63); | ||||||
|  |     std::uint64_t value_2 = (1ULL << 0); | ||||||
|  |     std::uint64_t value_3 = | ||||||
|  |         (1ULL << 0) | (1ULL << 1) | (1ULL << 2) | (1ULL << 3) | (1ULL << 4) | (1ULL << 5); | ||||||
|  | 
 | ||||||
|  |     CHECK_EQUAL_RANGE(makeBitRange<std::uint64_t>(value_1), 63, 33, 1, 0); | ||||||
|  |     CHECK_EQUAL_RANGE(makeBitRange<std::uint64_t>(value_2), 0); | ||||||
|  |     CHECK_EQUAL_RANGE(makeBitRange<std::uint64_t>(value_3), 5, 4, 3, 2, 1, 0); | ||||||
|  | 
 | ||||||
|  |     BOOST_CHECK_EQUAL(makeBitRange<std::uint64_t>(value_3).size(), 6); | ||||||
|  |     BOOST_CHECK_EQUAL(makeBitRange<std::uint64_t>(0).size(), 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | BOOST_AUTO_TEST_SUITE_END() | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user