From 27420e62ef0efdde3ba4e4eb8c19e902907e63e8 Mon Sep 17 00:00:00 2001 From: Vsevolod Novikov Date: Wed, 10 Feb 2021 11:34:42 +0300 Subject: [PATCH 01/10] #5325 show way_ids in annotations - implementation --- include/engine/api/flatbuffers/compile.sh | 3 ++ .../api/flatbuffers/fbresult_generated.h | 24 +++++++++-- include/engine/api/flatbuffers/route.fbs | 1 + include/engine/api/route_api.hpp | 21 +++++++++ include/engine/api/route_parameters.hpp | 3 +- .../contiguous_internalmem_datafacade.hpp | 9 ++++ include/engine/datafacade/datafacade_base.hpp | 7 +++ include/engine/guidance/assemble_geometry.hpp | 5 +++ include/engine/guidance/leg_geometry.hpp | 2 + include/engine/internal_route_result.hpp | 2 + .../routing_algorithms/routing_base.hpp | 7 +++ .../extractor/compressed_edge_container.hpp | 3 +- include/extractor/extractor.hpp | 1 + include/extractor/extractor_callbacks.hpp | 3 ++ include/extractor/internal_extractor_edge.hpp | 3 +- include/extractor/node_based_edge.hpp | 14 +++++- .../extractor/node_based_graph_factory.hpp | 3 +- include/extractor/segment_data_container.hpp | 37 ++++++++++++++-- include/extractor/serialization.hpp | 2 + include/nodejs/node_osrm_support.hpp | 5 +++ .../server/api/route_parameters_grammar.hpp | 6 ++- include/storage/view_factory.hpp | 3 ++ src/extractor/compressed_edge_container.cpp | 43 ++++++++++++++++++- src/extractor/extractor.cpp | 16 ++++++- src/extractor/extractor_callbacks.cpp | 4 ++ src/extractor/node_based_graph_factory.cpp | 7 +-- unit_tests/engine/offline_facade.cpp | 10 +++++ unit_tests/mocks/mock_datafacade.hpp | 10 +++++ 28 files changed, 232 insertions(+), 22 deletions(-) create mode 100755 include/engine/api/flatbuffers/compile.sh diff --git a/include/engine/api/flatbuffers/compile.sh b/include/engine/api/flatbuffers/compile.sh new file mode 100755 index 00000000000..b743be66568 --- /dev/null +++ b/include/engine/api/flatbuffers/compile.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +../../../../build/flatbuffers-build/flatc --cpp --no-includes --gen-all --gen-object-api fbresult.fbs diff --git a/include/engine/api/flatbuffers/fbresult_generated.h b/include/engine/api/flatbuffers/fbresult_generated.h index f3f05de4a2c..28198e0fb65 100644 --- a/include/engine/api/flatbuffers/fbresult_generated.h +++ b/include/engine/api/flatbuffers/fbresult_generated.h @@ -462,6 +462,7 @@ struct AnnotationT : public flatbuffers::NativeTable { std::vector duration; std::vector datasources; std::vector nodes; + std::vector ways; std::vector weight; std::vector speed; std::unique_ptr metadata; @@ -476,9 +477,10 @@ struct Annotation FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VT_DURATION = 6, VT_DATASOURCES = 8, VT_NODES = 10, - VT_WEIGHT = 12, - VT_SPEED = 14, - VT_METADATA = 16 + VT_WAYS = 12, + VT_WEIGHT = 14, + VT_SPEED = 16, + VT_METADATA = 18 }; const flatbuffers::Vector *distance() const { return GetPointer *>(VT_DISTANCE); @@ -492,6 +494,9 @@ struct Annotation FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { const flatbuffers::Vector *nodes() const { return GetPointer *>(VT_NODES); } + const flatbuffers::Vector *ways() const { + return GetPointer *>(VT_WAYS); + } const flatbuffers::Vector *weight() const { return GetPointer *>(VT_WEIGHT); } @@ -511,6 +516,8 @@ struct Annotation FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { verifier.VerifyVector(datasources()) && VerifyOffset(verifier, VT_NODES) && verifier.VerifyVector(nodes()) && + VerifyOffset(verifier, VT_WAYS) && + verifier.VerifyVector(ways()) && VerifyOffset(verifier, VT_WEIGHT) && verifier.VerifyVector(weight()) && VerifyOffset(verifier, VT_SPEED) && @@ -539,6 +546,9 @@ struct AnnotationBuilder { void add_nodes(flatbuffers::Offset> nodes) { fbb_.AddOffset(Annotation::VT_NODES, nodes); } + void add_ways(flatbuffers::Offset> ways) { + fbb_.AddOffset(Annotation::VT_WAYS, ways); + } void add_weight(flatbuffers::Offset> weight) { fbb_.AddOffset(Annotation::VT_WEIGHT, weight); } @@ -566,6 +576,7 @@ inline flatbuffers::Offset CreateAnnotation( flatbuffers::Offset> duration = 0, flatbuffers::Offset> datasources = 0, flatbuffers::Offset> nodes = 0, + flatbuffers::Offset> ways = 0, flatbuffers::Offset> weight = 0, flatbuffers::Offset> speed = 0, flatbuffers::Offset metadata = 0) { @@ -573,6 +584,7 @@ inline flatbuffers::Offset CreateAnnotation( builder_.add_metadata(metadata); builder_.add_speed(speed); builder_.add_weight(weight); + builder_.add_ways(ways); builder_.add_nodes(nodes); builder_.add_datasources(datasources); builder_.add_duration(duration); @@ -586,6 +598,7 @@ inline flatbuffers::Offset CreateAnnotationDirect( const std::vector *duration = nullptr, const std::vector *datasources = nullptr, const std::vector *nodes = nullptr, + const std::vector *ways = nullptr, const std::vector *weight = nullptr, const std::vector *speed = nullptr, flatbuffers::Offset metadata = 0) { @@ -593,6 +606,7 @@ inline flatbuffers::Offset CreateAnnotationDirect( auto duration__ = duration ? _fbb.CreateVector(*duration) : 0; auto datasources__ = datasources ? _fbb.CreateVector(*datasources) : 0; auto nodes__ = nodes ? _fbb.CreateVector(*nodes) : 0; + auto ways__ = ways ? _fbb.CreateVector(*ways) : 0; auto weight__ = weight ? _fbb.CreateVector(*weight) : 0; auto speed__ = speed ? _fbb.CreateVector(*speed) : 0; return osrm::engine::api::fbresult::CreateAnnotation( @@ -601,6 +615,7 @@ inline flatbuffers::Offset CreateAnnotationDirect( duration__, datasources__, nodes__, + ways__, weight__, speed__, metadata); @@ -1974,6 +1989,7 @@ inline void Annotation::UnPackTo(AnnotationT *_o, const flatbuffers::resolver_fu { auto _e = duration(); if (_e) { _o->duration.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->duration[_i] = _e->Get(_i); } } }; { auto _e = datasources(); if (_e) { _o->datasources.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->datasources[_i] = _e->Get(_i); } } }; { auto _e = nodes(); if (_e) { _o->nodes.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->nodes[_i] = _e->Get(_i); } } }; + { auto _e = ways(); if (_e) { _o->ways.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->ways[_i] = _e->Get(_i); } } }; { auto _e = weight(); if (_e) { _o->weight.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->weight[_i] = _e->Get(_i); } } }; { auto _e = speed(); if (_e) { _o->speed.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->speed[_i] = _e->Get(_i); } } }; { auto _e = metadata(); if (_e) _o->metadata = std::unique_ptr(_e->UnPack(_resolver)); }; @@ -1991,6 +2007,7 @@ inline flatbuffers::Offset CreateAnnotation(flatbuffers::FlatBufferB auto _duration = _o->duration.size() ? _fbb.CreateVector(_o->duration) : 0; auto _datasources = _o->datasources.size() ? _fbb.CreateVector(_o->datasources) : 0; auto _nodes = _o->nodes.size() ? _fbb.CreateVector(_o->nodes) : 0; + auto _ways = _o->ways.size() ? _fbb.CreateVector(_o->ways) : 0; auto _weight = _o->weight.size() ? _fbb.CreateVector(_o->weight) : 0; auto _speed = _o->speed.size() ? _fbb.CreateVector(_o->speed) : 0; auto _metadata = _o->metadata ? CreateMetadata(_fbb, _o->metadata.get(), _rehasher) : 0; @@ -2000,6 +2017,7 @@ inline flatbuffers::Offset CreateAnnotation(flatbuffers::FlatBufferB _duration, _datasources, _nodes, + _ways, _weight, _speed, _metadata); diff --git a/include/engine/api/flatbuffers/route.fbs b/include/engine/api/flatbuffers/route.fbs index 902bfa1990b..f826d5787f9 100644 --- a/include/engine/api/flatbuffers/route.fbs +++ b/include/engine/api/flatbuffers/route.fbs @@ -10,6 +10,7 @@ table Annotation { duration: [uint]; datasources: [uint]; nodes: [uint]; + ways: [uint]; weight: [uint]; speed: [float]; metadata: Metadata; diff --git a/include/engine/api/route_api.hpp b/include/engine/api/route_api.hpp index 4990d37c974..e1d4ae59762 100644 --- a/include/engine/api/route_api.hpp +++ b/include/engine/api/route_api.hpp @@ -503,7 +503,17 @@ class RouteAPI : public BaseAPI nodes.emplace_back(static_cast(node_id)); } } + std::vector ways; + if (requested_annotations & RouteParameters::AnnotationsType::Ways) + { + ways.reserve(leg_geometry.osm_way_ids.size()); + for (const auto way_id : leg_geometry.osm_way_ids) + { + ways.emplace_back(static_cast(way_id)); + } + } auto nodes_vector = fb_result.CreateVector(nodes); + auto ways_vector = fb_result.CreateVector(ways); // Add any supporting metadata, if needed bool use_metadata = requested_annotations & RouteParameters::AnnotationsType::Datasources; flatbuffers::Offset metadata_buffer; @@ -529,6 +539,7 @@ class RouteAPI : public BaseAPI annotation.add_weight(weight); annotation.add_datasources(datasources); annotation.add_nodes(nodes_vector); + annotation.add_ways(ways_vector); if (use_metadata) { annotation.add_metadata(metadata_buffer); @@ -832,6 +843,16 @@ class RouteAPI : public BaseAPI } annotation.values["nodes"] = std::move(nodes); } + if (requested_annotations & RouteParameters::AnnotationsType::Ways) + { + util::json::Array ways; + ways.values.reserve(leg_geometry.osm_way_ids.size()); + for (const auto way_id : leg_geometry.osm_way_ids) + { + ways.values.push_back(static_cast(way_id)); + } + annotation.values["ways"] = std::move(ways); + } // Add any supporting metadata, if needed if (requested_annotations & RouteParameters::AnnotationsType::Datasources) { diff --git a/include/engine/api/route_parameters.hpp b/include/engine/api/route_parameters.hpp index 8d5dd9ae46c..052b7c436c6 100644 --- a/include/engine/api/route_parameters.hpp +++ b/include/engine/api/route_parameters.hpp @@ -76,7 +76,8 @@ struct RouteParameters : public BaseParameters Weight = 0x08, Datasources = 0x10, Speed = 0x20, - All = Duration | Nodes | Distance | Weight | Datasources | Speed + Ways = 0x40, + All = Duration | Nodes | Distance | Weight | Datasources | Speed | Ways }; RouteParameters() = default; diff --git a/include/engine/datafacade/contiguous_internalmem_datafacade.hpp b/include/engine/datafacade/contiguous_internalmem_datafacade.hpp index 9886783312c..70b6d2d98d0 100644 --- a/include/engine/datafacade/contiguous_internalmem_datafacade.hpp +++ b/include/engine/datafacade/contiguous_internalmem_datafacade.hpp @@ -251,6 +251,15 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade return segment_data.GetReverseGeometry(id); } + OSMWayForwardRange GetUncompressedForwardWayIDs(const EdgeID id) const override final + { + return segment_data.GetForwardOSMWayIDs(id); + } + OSMWayReverseRange GetUncompressedReverseWayIDs(const EdgeID id) const override final + { + return segment_data.GetReverseOSMWayIDs(id); + } + DurationForwardRange GetUncompressedForwardDurations(const EdgeID id) const override final { return segment_data.GetForwardDurations(id); diff --git a/include/engine/datafacade/datafacade_base.hpp b/include/engine/datafacade/datafacade_base.hpp index b80c93b1879..839138643d3 100644 --- a/include/engine/datafacade/datafacade_base.hpp +++ b/include/engine/datafacade/datafacade_base.hpp @@ -57,6 +57,10 @@ class BaseDataFacade boost::iterator_range; using NodeReverseRange = boost::reversed_range; + using OSMWayForwardRange = + boost::iterator_range; + using OSMWayReverseRange = boost::reversed_range; + using WeightForwardRange = boost::iterator_range; using WeightReverseRange = boost::reversed_range; @@ -85,6 +89,9 @@ class BaseDataFacade virtual ComponentID GetComponentID(const NodeID id) const = 0; + virtual OSMWayForwardRange GetUncompressedForwardWayIDs(const EdgeID id) const = 0; + virtual OSMWayReverseRange GetUncompressedReverseWayIDs(const EdgeID id) const = 0; + virtual NodeForwardRange GetUncompressedForwardGeometry(const EdgeID id) const = 0; virtual NodeReverseRange GetUncompressedReverseGeometry(const EdgeID id) const = 0; diff --git a/include/engine/guidance/assemble_geometry.hpp b/include/engine/guidance/assemble_geometry.hpp index 9e3a0deafc5..b651fbd07fb 100644 --- a/include/engine/guidance/assemble_geometry.hpp +++ b/include/engine/guidance/assemble_geometry.hpp @@ -56,9 +56,11 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade, reversed_source ? source_node.reverse_segment_id.id : source_node.forward_segment_id.id; const auto source_geometry_id = facade.GetGeometryIndex(source_node_id).id; const auto source_geometry = facade.GetUncompressedForwardGeometry(source_geometry_id); + //const auto source_osm_way_ids = facade.GetUncompressedForwardWayIDs(source_geometry_id); geometry.osm_node_ids.push_back( facade.GetOSMNodeIDOfNode(source_geometry(source_segment_start_coordinate))); + // geometry.osm_way_ids.push_back(source_osm_way_ids(source_segment_start_coordinate))); auto cumulative_distance = 0.; auto current_distance = 0.; @@ -100,6 +102,7 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade, path_point.datasource_id}); geometry.locations.push_back(std::move(coordinate)); geometry.osm_node_ids.push_back(osm_node_id); + geometry.osm_way_ids.push_back(path_point.osm_way_id); } } current_distance = @@ -158,8 +161,10 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade, const auto target_segment_end_coordinate = target_node.fwd_segment_position + (reversed_target ? 0 : 1); const auto target_geometry = facade.GetUncompressedForwardGeometry(target_geometry_id); + const auto target_osm_way_ids = facade.GetUncompressedForwardWayIDs(target_geometry_id); geometry.osm_node_ids.push_back( facade.GetOSMNodeIDOfNode(target_geometry(target_segment_end_coordinate))); + geometry.osm_way_ids.push_back(target_osm_way_ids(target_node.fwd_segment_position)); BOOST_ASSERT(geometry.segment_distances.size() == geometry.segment_offsets.size() - 1); BOOST_ASSERT(geometry.locations.size() > geometry.segment_distances.size()); diff --git a/include/engine/guidance/leg_geometry.hpp b/include/engine/guidance/leg_geometry.hpp index 8374bb99261..daccff8fcef 100644 --- a/include/engine/guidance/leg_geometry.hpp +++ b/include/engine/guidance/leg_geometry.hpp @@ -33,6 +33,8 @@ struct LegGeometry std::vector segment_distances; // original OSM node IDs for each coordinate std::vector osm_node_ids; + // original OSM way IDs between every pair of nodes + std::vector osm_way_ids; // Per-coordinate metadata struct Annotation diff --git a/include/engine/internal_route_result.hpp b/include/engine/internal_route_result.hpp index 9f5443ffa0f..6c7193dc504 100644 --- a/include/engine/internal_route_result.hpp +++ b/include/engine/internal_route_result.hpp @@ -26,6 +26,8 @@ struct PathData { // from edge-based-node id NodeID from_edge_based_node; + // OSM Way ID of the edge immediately followed by via node + OSMWayID osm_way_id; // the internal OSRM id of the OSM node id that is the via node of the turn NodeID turn_via_node; // name of the street that leads to the turn diff --git a/include/engine/routing_algorithms/routing_base.hpp b/include/engine/routing_algorithms/routing_base.hpp index ee564afe207..855c38d241b 100644 --- a/include/engine/routing_algorithms/routing_base.hpp +++ b/include/engine/routing_algorithms/routing_base.hpp @@ -144,6 +144,7 @@ void annotatePath(const FacadeT &facade, // datastructures to hold extracted data from geometry std::vector id_vector; + std::vector osm_way_id_vector; std::vector weight_vector; std::vector duration_vector; std::vector datasource_vector; @@ -157,6 +158,8 @@ void annotatePath(const FacadeT &facade, if (geometry_index.forward) { copy(id_vector, facade.GetUncompressedForwardGeometry(geometry_index.id)); + copy(osm_way_id_vector, facade.GetUncompressedForwardWayIDs(geometry_index.id)); + copy(weight_vector, facade.GetUncompressedForwardWeights(geometry_index.id)); copy(duration_vector, facade.GetUncompressedForwardDurations(geometry_index.id)); copy(datasource_vector, facade.GetUncompressedForwardDatasources(geometry_index.id)); @@ -164,6 +167,8 @@ void annotatePath(const FacadeT &facade, else { copy(id_vector, facade.GetUncompressedReverseGeometry(geometry_index.id)); + copy(osm_way_id_vector, facade.GetUncompressedReverseWayIDs(geometry_index.id)); + copy(weight_vector, facade.GetUncompressedReverseWeights(geometry_index.id)); copy(duration_vector, facade.GetUncompressedReverseDurations(geometry_index.id)); copy(datasource_vector, facade.GetUncompressedReverseDatasources(geometry_index.id)); @@ -213,6 +218,7 @@ void annotatePath(const FacadeT &facade, { unpacked_path.push_back( PathData{*node_from, + osm_way_id_vector[segment_idx], id_vector[segment_idx + 1], name_index, is_segregated, @@ -288,6 +294,7 @@ void annotatePath(const FacadeT &facade, BOOST_ASSERT(facade.GetTravelMode(target_node_id) > 0); unpacked_path.push_back( PathData{target_node_id, + osm_way_id_vector[segment_idx], id_vector[start_index < end_index ? segment_idx + 1 : segment_idx - 1], facade.GetNameIndex(target_node_id), facade.IsSegregated(target_node_id), diff --git a/include/extractor/compressed_edge_container.hpp b/include/extractor/compressed_edge_container.hpp index ec9e1f9eaef..904369b0e95 100644 --- a/include/extractor/compressed_edge_container.hpp +++ b/include/extractor/compressed_edge_container.hpp @@ -2,6 +2,7 @@ #define GEOMETRY_COMPRESSOR_HPP_ #include "extractor/segment_data_container.hpp" +#include "extractor/node_based_edge.hpp" #include "util/typedefs.hpp" @@ -48,7 +49,7 @@ class CompressedEdgeContainer const SegmentWeight duration); void InitializeBothwayVector(); - unsigned ZipEdges(const unsigned f_edge_pos, const unsigned r_edge_pos); + unsigned ZipEdges(const unsigned f_edge_pos, const unsigned r_edge_pos, OSMWayIDMap &osm_way_id_map); bool HasEntryForID(const EdgeID edge_id) const; bool HasZippedEntryForForwardID(const EdgeID edge_id) const; diff --git a/include/extractor/extractor.hpp b/include/extractor/extractor.hpp index 070a3b4ef59..441a4a75482 100644 --- a/include/extractor/extractor.hpp +++ b/include/extractor/extractor.hpp @@ -63,6 +63,7 @@ class Extractor ExtractorConfig config; std::tuple, std::vector> ParseOSMData(ScriptingEnvironment &scripting_environment, const unsigned number_of_threads); diff --git a/include/extractor/extractor_callbacks.hpp b/include/extractor/extractor_callbacks.hpp index 9939a49631c..197f663ad98 100644 --- a/include/extractor/extractor_callbacks.hpp +++ b/include/extractor/extractor_callbacks.hpp @@ -2,6 +2,7 @@ #define EXTRACTOR_CALLBACKS_HPP #include "extractor/class_data.hpp" +#include "extractor/node_based_edge.hpp" #include "extractor/turn_lane_types.hpp" #include "util/typedefs.hpp" @@ -69,6 +70,7 @@ class ExtractorCallbacks ExtractionContainers &external_memory; std::unordered_map &classes_map; LaneDescriptionMap &lane_description_map; + OSMWayIDMap &osm_way_id_map; bool fallback_to_duration; bool force_split_edges; @@ -78,6 +80,7 @@ class ExtractorCallbacks explicit ExtractorCallbacks(ExtractionContainers &extraction_containers, std::unordered_map &classes_map, LaneDescriptionMap &lane_description_map, + OSMWayIDMap &osm_way_id_map, const ProfileProperties &properties); ExtractorCallbacks(const ExtractorCallbacks &) = delete; diff --git a/include/extractor/internal_extractor_edge.hpp b/include/extractor/internal_extractor_edge.hpp index c7ee904d937..5000352bb49 100644 --- a/include/extractor/internal_extractor_edge.hpp +++ b/include/extractor/internal_extractor_edge.hpp @@ -60,10 +60,11 @@ struct InternalExtractorEdge explicit InternalExtractorEdge(OSMNodeID source, OSMNodeID target, + OSMWayID way, WeightData weight_data, DurationData duration_data, util::Coordinate source_coordinate) - : result(source, target, 0, 0, 0, {}, -1, {}), weight_data(std::move(weight_data)), + : result(source, target, way, 0, 0, 0, {}, -1, {}), weight_data(std::move(weight_data)), duration_data(std::move(duration_data)), source_coordinate(std::move(source_coordinate)) { } diff --git a/include/extractor/node_based_edge.hpp b/include/extractor/node_based_edge.hpp index 84a03d0a09b..44f198da74e 100644 --- a/include/extractor/node_based_edge.hpp +++ b/include/extractor/node_based_edge.hpp @@ -3,6 +3,7 @@ #include #include +#include #include "extractor/class_data.hpp" #include "extractor/travel_mode.hpp" @@ -15,6 +16,12 @@ namespace osrm namespace extractor { +// Intermediate map to lookup OSMWayID by neighbor nbg node pair +// while CompressedEdgeContainer::ZipEdges and store it in the segment data +// to use when building found path annotations +using OSMWayIDMapKey = std::pair; +using OSMWayIDMap = std::map; + // Flags describing the class of the road. This data is used during creation of graphs/guidance // generation but is not available in annotation/navigation struct NodeBasedEdgeClassification @@ -120,6 +127,7 @@ struct NodeBasedEdgeWithOSM : NodeBasedEdge NodeBasedEdgeWithOSM(OSMNodeID source, OSMNodeID target, + OSMWayID way, EdgeWeight weight, EdgeDuration duration, EdgeDistance distance, @@ -129,6 +137,7 @@ struct NodeBasedEdgeWithOSM : NodeBasedEdge OSMNodeID osm_source_id; OSMNodeID osm_target_id; + OSMWayID osm_way_id; }; // Impl. @@ -178,6 +187,7 @@ inline bool NodeBasedEdge::operator<(const NodeBasedEdge &other) const inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM(OSMNodeID source, OSMNodeID target, + OSMWayID way, EdgeWeight weight, EdgeDuration duration, EdgeDistance distance, @@ -192,12 +202,12 @@ inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM(OSMNodeID source, geometry_id, annotation_data, flags), - osm_source_id(std::move(source)), osm_target_id(std::move(target)) + osm_source_id(std::move(source)), osm_target_id(std::move(target)), osm_way_id(std::move(way)) { } inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM() - : osm_source_id(MIN_OSM_NODEID), osm_target_id(MIN_OSM_NODEID) + : osm_source_id(MIN_OSM_NODEID), osm_target_id(MIN_OSM_NODEID), osm_way_id(MIN_OSM_WAYID) { } diff --git a/include/extractor/node_based_graph_factory.hpp b/include/extractor/node_based_graph_factory.hpp index e3fc395839e..7b44e7bd60a 100644 --- a/include/extractor/node_based_graph_factory.hpp +++ b/include/extractor/node_based_graph_factory.hpp @@ -39,6 +39,7 @@ class NodeBasedGraphFactory // turn the graph into the routing graph to be used with the navigation algorithms. NodeBasedGraphFactory(const boost::filesystem::path &input_file, ScriptingEnvironment &scripting_environment, + OSMWayIDMap &osm_way_id_map, std::vector &turn_restrictions, std::vector &maneuver_overrides); @@ -73,7 +74,7 @@ class NodeBasedGraphFactory // Most ways are bidirectional, making the geometry in forward and backward direction the same, // except for reversal. We make use of this fact by keeping only one representation of the // geometry around - void CompressGeometry(); + void CompressGeometry(OSMWayIDMap &osm_way_id_map); // After graph compression, some of the annotation entries might not be referenced anymore. We // compress the annotation data by relabeling the node-based graph references and removing all diff --git a/include/extractor/segment_data_container.hpp b/include/extractor/segment_data_container.hpp index 580c018ed75..76d3b5c0a48 100644 --- a/include/extractor/segment_data_container.hpp +++ b/include/extractor/segment_data_container.hpp @@ -56,6 +56,7 @@ template class SegmentDataContainerImpl using DirectionalGeometryID = std::uint32_t; using SegmentOffset = std::uint32_t; using SegmentNodeVector = Vector; + using SegmentOSMWayVector = Vector; using SegmentWeightVector = PackedVector; using SegmentDurationVector = PackedVector; using SegmentDatasourceVector = Vector; @@ -64,16 +65,17 @@ template class SegmentDataContainerImpl SegmentDataContainerImpl(Vector index_, SegmentNodeVector nodes_, + SegmentOSMWayVector osm_ways_, SegmentWeightVector fwd_weights_, SegmentWeightVector rev_weights_, SegmentDurationVector fwd_durations_, SegmentDurationVector rev_durations_, SegmentDatasourceVector fwd_datasources_, SegmentDatasourceVector rev_datasources_) - : index(std::move(index_)), nodes(std::move(nodes_)), fwd_weights(std::move(fwd_weights_)), - rev_weights(std::move(rev_weights_)), fwd_durations(std::move(fwd_durations_)), - rev_durations(std::move(rev_durations_)), fwd_datasources(std::move(fwd_datasources_)), - rev_datasources(std::move(rev_datasources_)) + : index(std::move(index_)), nodes(std::move(nodes_)), osm_ways(std::move(osm_ways_)), + fwd_weights(std::move(fwd_weights_)), rev_weights(std::move(rev_weights_)), + fwd_durations(std::move(fwd_durations_)), rev_durations(std::move(rev_durations_)), + fwd_datasources(std::move(fwd_datasources_)), rev_datasources(std::move(rev_datasources_)) { } @@ -90,6 +92,19 @@ template class SegmentDataContainerImpl return boost::adaptors::reverse(GetForwardGeometry(id)); } + auto GetForwardOSMWayIDs(const DirectionalGeometryID id) + { + const auto begin = osm_ways.begin() + index[id]; + const auto end = osm_ways.begin() + index[id + 1] - 1; + + return boost::make_iterator_range(begin, end); + } + + auto GetReverseOSMWayIDs(const DirectionalGeometryID id) + { + return boost::adaptors::reverse(GetForwardOSMWayIDs(id)); + } + auto GetForwardDurations(const DirectionalGeometryID id) { const auto begin = fwd_durations.begin() + index[id] + 1; @@ -151,6 +166,19 @@ template class SegmentDataContainerImpl return boost::adaptors::reverse(GetForwardGeometry(id)); } + auto GetForwardOSMWayIDs(const DirectionalGeometryID id) const + { + const auto begin = osm_ways.cbegin() + index[id]; + const auto end = osm_ways.cbegin() + index[id + 1] - 1; + + return boost::make_iterator_range(begin, end); + } + + auto GetReverseOSMWayIDs(const DirectionalGeometryID id) const + { + return boost::adaptors::reverse(GetForwardOSMWayIDs(id)); + } + auto GetForwardDurations(const DirectionalGeometryID id) const { const auto begin = fwd_durations.cbegin() + index[id] + 1; @@ -214,6 +242,7 @@ template class SegmentDataContainerImpl private: Vector index; SegmentNodeVector nodes; + SegmentOSMWayVector osm_ways; SegmentWeightVector fwd_weights; SegmentWeightVector rev_weights; SegmentDurationVector fwd_durations; diff --git a/include/extractor/serialization.hpp b/include/extractor/serialization.hpp index 363dd9c168e..3ec5ae177e0 100644 --- a/include/extractor/serialization.hpp +++ b/include/extractor/serialization.hpp @@ -84,6 +84,7 @@ inline void read(storage::tar::FileReader &reader, { storage::serialization::read(reader, name + "/index", segment_data.index); storage::serialization::read(reader, name + "/nodes", segment_data.nodes); + storage::serialization::read(reader, name + "/osm_ways", segment_data.osm_ways); util::serialization::read(reader, name + "/forward_weights", segment_data.fwd_weights); util::serialization::read(reader, name + "/reverse_weights", segment_data.rev_weights); util::serialization::read(reader, name + "/forward_durations", segment_data.fwd_durations); @@ -101,6 +102,7 @@ inline void write(storage::tar::FileWriter &writer, { storage::serialization::write(writer, name + "/index", segment_data.index); storage::serialization::write(writer, name + "/nodes", segment_data.nodes); + storage::serialization::write(writer, name + "/osm_ways", segment_data.osm_ways); util::serialization::write(writer, name + "/forward_weights", segment_data.fwd_weights); util::serialization::write(writer, name + "/reverse_weights", segment_data.rev_weights); util::serialization::write(writer, name + "/forward_durations", segment_data.fwd_durations); diff --git a/include/nodejs/node_osrm_support.hpp b/include/nodejs/node_osrm_support.hpp index 400d420a52b..cafae9a5d61 100644 --- a/include/nodejs/node_osrm_support.hpp +++ b/include/nodejs/node_osrm_support.hpp @@ -762,6 +762,11 @@ inline bool parseCommonParameters(const v8::Local &obj, ParamType &p params->annotations_type = params->annotations_type | osrm::RouteParameters::AnnotationsType::Nodes; } + else if (annotations_str == "ways") + { + params->annotations_type = + params->annotations_type | osrm::RouteParameters::AnnotationsType::Ways; + } else if (annotations_str == "distance") { params->annotations_type = diff --git a/include/server/api/route_parameters_grammar.hpp b/include/server/api/route_parameters_grammar.hpp index df5fb52df2d..dc005043b8f 100644 --- a/include/server/api/route_parameters_grammar.hpp +++ b/include/server/api/route_parameters_grammar.hpp @@ -73,8 +73,10 @@ struct RouteParametersGrammar : public BaseParametersGrammar(index, name + "/osm_ways"); + extractor::SegmentDataView::SegmentWeightVector fwd_weight_list( make_vector_view( index, name + "/forward_weights/packed"), @@ -162,6 +164,7 @@ inline auto make_segment_data_view(const SharedDataIndex &index, const std::stri return extractor::SegmentDataView{std::move(geometry_begin_indices), std::move(node_list), + std::move(osm_way_list), std::move(fwd_weight_list), std::move(rev_weight_list), std::move(fwd_duration_list), diff --git a/src/extractor/compressed_edge_container.cpp b/src/extractor/compressed_edge_container.cpp index 7510f85b04e..81b2e631c56 100644 --- a/src/extractor/compressed_edge_container.cpp +++ b/src/extractor/compressed_edge_container.cpp @@ -262,7 +262,7 @@ void CompressedEdgeContainer::InitializeBothwayVector() segment_data->rev_datasources.reserve(m_compressed_oneway_geometries.size()); } -unsigned CompressedEdgeContainer::ZipEdges(const EdgeID f_edge_id, const EdgeID r_edge_id) +unsigned CompressedEdgeContainer::ZipEdges(const EdgeID f_edge_id, const EdgeID r_edge_id, OSMWayIDMap &osm_way_id_map) { if (!segment_data) InitializeBothwayVector(); @@ -279,7 +279,8 @@ unsigned CompressedEdgeContainer::ZipEdges(const EdgeID f_edge_id, const EdgeID segment_data->index.emplace_back(segment_data->nodes.size()); const auto &first_node = reverse_bucket.back(); - + auto prev_node_id = first_node.node_id; + auto osm_way_id = SPECIAL_OSM_WAYID; constexpr DatasourceID LUA_SOURCE = 0; segment_data->nodes.emplace_back(first_node.node_id); @@ -297,6 +298,23 @@ unsigned CompressedEdgeContainer::ZipEdges(const EdgeID f_edge_id, const EdgeID BOOST_ASSERT(fwd_node.node_id == rev_node.node_id); + auto node_id = fwd_node.node_id; + if( node_id != prev_node_id ) { + auto find_way_id = osm_way_id_map.find( OSMWayIDMapKey(prev_node_id, node_id) ); + if( find_way_id == osm_way_id_map.cend() ) { + find_way_id = osm_way_id_map.find( OSMWayIDMapKey(node_id, prev_node_id) ); + } + if( find_way_id == osm_way_id_map.cend() ) { + util::Log(logERROR) << "OSM Way ID not found for (nbg) nodes, it should never be happened: " << prev_node_id << "<-x->" << node_id; + segment_data->osm_ways.emplace_back(osm_way_id); + } else { + segment_data->osm_ways.emplace_back(osm_way_id = find_way_id->second); + } + } else { + // Special case (artificial lighting signal edge) + segment_data->osm_ways.emplace_back(osm_way_id); + } + segment_data->nodes.emplace_back(fwd_node.node_id); segment_data->fwd_weights.emplace_back(fwd_node.weight); segment_data->rev_weights.emplace_back(rev_node.weight); @@ -304,9 +322,30 @@ unsigned CompressedEdgeContainer::ZipEdges(const EdgeID f_edge_id, const EdgeID segment_data->rev_durations.emplace_back(rev_node.duration); segment_data->fwd_datasources.emplace_back(LUA_SOURCE); segment_data->rev_datasources.emplace_back(LUA_SOURCE); + prev_node_id = node_id; } const auto &last_node = forward_bucket.back(); + auto node_id = last_node.node_id; + if( node_id != prev_node_id ) { + auto find_way_id = osm_way_id_map.find( OSMWayIDMapKey(prev_node_id, node_id) ); + if( find_way_id == osm_way_id_map.cend() ) { + find_way_id = osm_way_id_map.find( OSMWayIDMapKey(node_id, prev_node_id) ); + } + if( find_way_id == osm_way_id_map.cend() ) { + util::Log(logERROR) << "OSM Way ID not found for (nbg) nodes, it should never be happened: " << prev_node_id << "<-x->" << node_id; + segment_data->osm_ways.emplace_back(osm_way_id); + } else { + segment_data->osm_ways.emplace_back(osm_way_id = find_way_id->second); + } + } else { + // Special case (artificial lighting signal edge) + segment_data->osm_ways.emplace_back(osm_way_id); + } + + // Make osm_ways vector size the same as + // nodes vector size to use index vector for the both + segment_data->osm_ways.emplace_back(osm_way_id); segment_data->nodes.emplace_back(last_node.node_id); segment_data->fwd_weights.emplace_back(last_node.weight); diff --git a/src/extractor/extractor.cpp b/src/extractor/extractor.cpp index 5c5d96a7100..641e80b345b 100644 --- a/src/extractor/extractor.cpp +++ b/src/extractor/extractor.cpp @@ -215,9 +215,10 @@ int Extractor::run(ScriptingEnvironment &scripting_environment) #endif LaneDescriptionMap turn_lane_map; + OSMWayIDMap osm_way_id_map; std::vector turn_restrictions; std::vector unresolved_maneuver_overrides; - std::tie(turn_lane_map, turn_restrictions, unresolved_maneuver_overrides) = + std::tie(turn_lane_map, osm_way_id_map, turn_restrictions, unresolved_maneuver_overrides) = ParseOSMData(scripting_environment, number_of_threads); // Transform the node-based graph that OSM is based on into an edge-based graph @@ -238,6 +239,7 @@ int Extractor::run(ScriptingEnvironment &scripting_environment) // Create a node-based graph from the OSRM file NodeBasedGraphFactory node_based_graph_factory(config.GetPath(".osrm"), scripting_environment, + osm_way_id_map, turn_restrictions, unresolved_maneuver_overrides); @@ -369,7 +371,7 @@ int Extractor::run(ScriptingEnvironment &scripting_environment) } std:: - tuple, std::vector> + tuple, std::vector> Extractor::ParseOSMData(ScriptingEnvironment &scripting_environment, const unsigned number_of_threads) { @@ -420,10 +422,12 @@ std:: ExtractionContainers extraction_containers; ExtractorCallbacks::ClassesMap classes_map; LaneDescriptionMap turn_lane_map; + OSMWayIDMap osm_way_id_map; auto extractor_callbacks = std::make_unique(extraction_containers, classes_map, turn_lane_map, + osm_way_id_map, scripting_environment.GetProfileProperties()); // get list of supported relation types @@ -626,10 +630,18 @@ std:: SetExcludableClasses(classes_map, excludable_classes, profile_properties); files::writeProfileProperties(config.GetPath(".osrm.properties").string(), profile_properties); + // Fill OSM Way ID Lookup Map to use it later + for(auto edge: extraction_containers.all_edges_list) { + osm_way_id_map[ + OSMWayIDMapKey(edge.result.source, edge.result.target) + ] = edge.result.osm_way_id; + } + TIMER_STOP(extracting); util::Log() << "extraction finished after " << TIMER_SEC(extracting) << "s"; return std::make_tuple(std::move(turn_lane_map), + std::move(osm_way_id_map), std::move(extraction_containers.turn_restrictions), std::move(extraction_containers.internal_maneuver_overrides)); } diff --git a/src/extractor/extractor_callbacks.cpp b/src/extractor/extractor_callbacks.cpp index de7b282193c..4b6bf84e2b5 100644 --- a/src/extractor/extractor_callbacks.cpp +++ b/src/extractor/extractor_callbacks.cpp @@ -29,9 +29,11 @@ namespace extractor ExtractorCallbacks::ExtractorCallbacks(ExtractionContainers &extraction_containers_, std::unordered_map &classes_map, LaneDescriptionMap &lane_description_map, + OSMWayIDMap &osm_way_id_map, const ProfileProperties &properties) : external_memory(extraction_containers_), classes_map(classes_map), lane_description_map(lane_description_map), + osm_way_id_map(osm_way_id_map), fallback_to_duration(properties.fallback_to_duration), force_split_edges(properties.force_split_edges) { @@ -409,6 +411,7 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti NodeBasedEdgeWithOSM edge = { OSMNodeID{static_cast(first_node.ref())}, OSMNodeID{static_cast(last_node.ref())}, + OSMWayID{static_cast(input_way.id())}, 0, // weight 0, // duration 0, // distance @@ -445,6 +448,7 @@ void ExtractorCallbacks::ProcessWay(const osmium::Way &input_way, const Extracti NodeBasedEdgeWithOSM edge = { OSMNodeID{static_cast(first_node.ref())}, OSMNodeID{static_cast(last_node.ref())}, + OSMWayID{static_cast(input_way.id())}, 0, // weight 0, // duration 0, // distance diff --git a/src/extractor/node_based_graph_factory.cpp b/src/extractor/node_based_graph_factory.cpp index 51473797d2f..6ae8dbf9478 100644 --- a/src/extractor/node_based_graph_factory.cpp +++ b/src/extractor/node_based_graph_factory.cpp @@ -18,12 +18,13 @@ namespace extractor NodeBasedGraphFactory::NodeBasedGraphFactory( const boost::filesystem::path &input_file, ScriptingEnvironment &scripting_environment, + OSMWayIDMap &osm_way_id_map, std::vector &turn_restrictions, std::vector &maneuver_overrides) { LoadDataFromFile(input_file); Compress(scripting_environment, turn_restrictions, maneuver_overrides); - CompressGeometry(); + CompressGeometry(osm_way_id_map); CompressAnnotationData(); } @@ -93,7 +94,7 @@ void NodeBasedGraphFactory::Compress(ScriptingEnvironment &scripting_environment compressed_edge_container); } -void NodeBasedGraphFactory::CompressGeometry() +void NodeBasedGraphFactory::CompressGeometry(OSMWayIDMap &osm_way_id_map) { for (const auto nbg_node_u : util::irange(0u, compressed_output_graph.GetNumberOfNodes())) { @@ -126,7 +127,7 @@ void NodeBasedGraphFactory::CompressGeometry() const EdgeID edge_id_2 = compressed_output_graph.FindEdge(to, from); BOOST_ASSERT(edge_id_2 != SPECIAL_EDGEID); - auto packed_geometry_id = compressed_edge_container.ZipEdges(edge_id_1, edge_id_2); + auto packed_geometry_id = compressed_edge_container.ZipEdges(edge_id_1, edge_id_2, osm_way_id_map); // remember the geometry ID for both edges in the node-based graph compressed_output_graph.GetEdgeData(edge_id_1).geometry_id = {packed_geometry_id, true}; diff --git a/unit_tests/engine/offline_facade.cpp b/unit_tests/engine/offline_facade.cpp index 7c264e17695..e6c9d70b045 100644 --- a/unit_tests/engine/offline_facade.cpp +++ b/unit_tests/engine/offline_facade.cpp @@ -166,6 +166,16 @@ class ContiguousInternalMemoryDataFacade return NodeReverseRange(NodeForwardRange()); } + OSMWayForwardRange GetUncompressedForwardWayIDs(const EdgeID /*id*/) const override + { + return {}; + } + + OSMWayReverseRange GetUncompressedReverseWayIDs(const EdgeID /*id*/) const override + { + return OSMWayReverseRange(OSMWayForwardRange()); + } + TurnPenalty GetWeightPenaltyForEdgeID(const unsigned /*id*/) const override { return INVALID_TURN_PENALTY; diff --git a/unit_tests/mocks/mock_datafacade.hpp b/unit_tests/mocks/mock_datafacade.hpp index 4edcb97356e..2270bfffd7c 100644 --- a/unit_tests/mocks/mock_datafacade.hpp +++ b/unit_tests/mocks/mock_datafacade.hpp @@ -64,6 +64,16 @@ class MockBaseDataFacade : public engine::datafacade::BaseDataFacade { return NodeReverseRange(GetUncompressedForwardGeometry(id)); } + OSMWayForwardRange GetUncompressedForwardWayIDs(const EdgeID /* id */) const override + { + static OSMWayID data[] = {0, 1, 2, 3}; + static extractor::SegmentDataView::SegmentOSMWayVector ways(data, 4); + return boost::make_iterator_range(ways.cbegin(), ways.cend()); + } + OSMWayReverseRange GetUncompressedReverseWayIDs(const EdgeID id) const override + { + return OSMWayReverseRange(GetUncompressedForwardWayIDs(id)); + } WeightForwardRange GetUncompressedForwardWeights(const EdgeID /* id */) const override { static std::uint64_t data[] = {1, 2, 3}; From c2015a839382cba16bf78d0a8a243c159d4fe2f0 Mon Sep 17 00:00:00 2001 From: Vsevolod Novikov Date: Mon, 15 Feb 2021 14:33:32 +0300 Subject: [PATCH 02/10] #5325 unit tests and fixes after tests --- .../routing_algorithms/routing_base.hpp | 1 + src/engine/guidance/post_processing.cpp | 4 + .../engine/collapse_internal_route_result.cpp | 26 +-- unit_tests/library/route.cpp | 164 +++++++++++++++++- 4 files changed, 181 insertions(+), 14 deletions(-) diff --git a/include/engine/routing_algorithms/routing_base.hpp b/include/engine/routing_algorithms/routing_base.hpp index 855c38d241b..c4a5007fc61 100644 --- a/include/engine/routing_algorithms/routing_base.hpp +++ b/include/engine/routing_algorithms/routing_base.hpp @@ -194,6 +194,7 @@ void annotatePath(const FacadeT &facade, BOOST_ASSERT(datasource_vector.size() > 0); BOOST_ASSERT(weight_vector.size() + 1 == id_vector.size()); BOOST_ASSERT(duration_vector.size() + 1 == id_vector.size()); + BOOST_ASSERT(osm_way_id_vector.size() + 1 == id_vector.size()); const bool is_first_segment = unpacked_path.empty(); diff --git a/src/engine/guidance/post_processing.cpp b/src/engine/guidance/post_processing.cpp index b5a28047210..6161845ab00 100644 --- a/src/engine/guidance/post_processing.cpp +++ b/src/engine/guidance/post_processing.cpp @@ -281,6 +281,8 @@ void trimShortSegments(std::vector &steps, LegGeometry &geometry) geometry.annotations.begin() + offset); geometry.osm_node_ids.erase(geometry.osm_node_ids.begin(), geometry.osm_node_ids.begin() + offset); + geometry.osm_way_ids.erase(geometry.osm_way_ids.begin(), + geometry.osm_way_ids.begin() + offset); } auto const first_bearing = steps.front().maneuver.bearing_after; @@ -378,6 +380,7 @@ void trimShortSegments(std::vector &steps, LegGeometry &geometry) geometry.locations.resize(geometry.segment_offsets.back() + 1); geometry.annotations.resize(geometry.segment_offsets.back()); geometry.osm_node_ids.resize(geometry.segment_offsets.back() + 1); + geometry.osm_way_ids.resize(geometry.segment_offsets.back()); BOOST_ASSERT(geometry.segment_distances.back() <= 1); geometry.segment_distances.pop_back(); @@ -415,6 +418,7 @@ void trimShortSegments(std::vector &steps, LegGeometry &geometry) geometry.locations.pop_back(); geometry.annotations.pop_back(); geometry.osm_node_ids.pop_back(); + geometry.osm_way_ids.pop_back(); geometry.segment_offsets.back()--; // since the last geometry includes the location of arrival, the arrival instruction // geometry overlaps with the previous segment diff --git a/unit_tests/engine/collapse_internal_route_result.cpp b/unit_tests/engine/collapse_internal_route_result.cpp index fc989ba5714..52a097b4754 100644 --- a/unit_tests/engine/collapse_internal_route_result.cpp +++ b/unit_tests/engine/collapse_internal_route_result.cpp @@ -19,8 +19,8 @@ BOOST_AUTO_TEST_CASE(unchanged_collapse_route_result) PhantomNode target; source.forward_segment_id = {1, true}; target.forward_segment_id = {6, true}; - PathData pathy{0, 2, 17, false, 2, 3, 4, 5, 0, {}, 4, 2, {}, 2, {1.0}, {1.0}, false}; - PathData kathy{0, 1, 16, false, 1, 2, 3, 4, 1, {}, 3, 1, {}, 1, {2.0}, {3.0}, false}; + PathData pathy{0, 0, 2, 17, false, 2, 3, 4, 5, 0, {}, 4, 2, {}, 2, {1.0}, {1.0}, false}; + PathData kathy{0, 0, 1, 16, false, 1, 2, 3, 4, 1, {}, 3, 1, {}, 1, {2.0}, {3.0}, false}; InternalRouteResult one_leg_result; one_leg_result.unpacked_path_segments = {{pathy, kathy}}; one_leg_result.segment_end_coordinates = {PhantomNodes{source, target}}; @@ -41,9 +41,9 @@ BOOST_AUTO_TEST_CASE(two_legs_to_one_leg) // weight_of_turn, // duration_until_turn, duration_of_turn, turn_instruction, lane_data, travel_mode, classes, // entry_class, datasource_id, pre_turn_bearing, post_turn_bearing, left_hand - PathData pathy{0, 2, 17, false, 2, 3, 4, 5, 0, {}, 4, 2, {}, 2, {1.0}, {1.0}, false}; - PathData kathy{0, 1, 16, false, 1, 2, 3, 4, 1, {}, 3, 1, {}, 1, {2.0}, {3.0}, false}; - PathData cathy{0, 3, 16, false, 1, 2, 3, 4, 1, {}, 3, 1, {}, 1, {2.0}, {3.0}, false}; + PathData pathy{0, 0, 2, 17, false, 2, 3, 4, 5, 0, {}, 4, 2, {}, 2, {1.0}, {1.0}, false}; + PathData kathy{0, 0, 1, 16, false, 1, 2, 3, 4, 1, {}, 3, 1, {}, 1, {2.0}, {3.0}, false}; + PathData cathy{0, 0, 3, 16, false, 1, 2, 3, 4, 1, {}, 3, 1, {}, 1, {2.0}, {3.0}, false}; PhantomNode node_1; PhantomNode node_2; PhantomNode node_3; @@ -73,11 +73,11 @@ BOOST_AUTO_TEST_CASE(two_legs_to_one_leg) BOOST_AUTO_TEST_CASE(three_legs_to_two_legs) { - PathData pathy{0, 2, 17, false, 2, 3, 4, 5, 0, {}, 4, 2, {}, 2, {1.0}, {1.0}, false}; - PathData kathy{0, 1, 16, false, 1, 2, 3, 4, 1, {}, 3, 1, {}, 1, {2.0}, {3.0}, false}; - PathData qathy{0, 5, 16, false, 1, 2, 3, 4, 1, {}, 3, 1, {}, 1, {2.0}, {3.0}, false}; - PathData cathy{0, 3, 16, false, 1, 2, 3, 4, 1, {}, 3, 1, {}, 1, {2.0}, {3.0}, false}; - PathData mathy{0, 4, 18, false, 8, 9, 13, 4, 2, {}, 4, 2, {}, 2, {3.0}, {1.0}, false}; + PathData pathy{0, 0, 2, 17, false, 2, 3, 4, 5, 0, {}, 4, 2, {}, 2, {1.0}, {1.0}, false}; + PathData kathy{0, 0, 1, 16, false, 1, 2, 3, 4, 1, {}, 3, 1, {}, 1, {2.0}, {3.0}, false}; + PathData qathy{0, 0, 5, 16, false, 1, 2, 3, 4, 1, {}, 3, 1, {}, 1, {2.0}, {3.0}, false}; + PathData cathy{0, 0, 3, 16, false, 1, 2, 3, 4, 1, {}, 3, 1, {}, 1, {2.0}, {3.0}, false}; + PathData mathy{0, 0, 4, 18, false, 8, 9, 13, 4, 2, {}, 4, 2, {}, 2, {3.0}, {1.0}, false}; PhantomNode node_1; PhantomNode node_2; PhantomNode node_3; @@ -117,9 +117,9 @@ BOOST_AUTO_TEST_CASE(three_legs_to_two_legs) BOOST_AUTO_TEST_CASE(two_legs_to_two_legs) { - PathData pathy{0, 2, 17, false, 2, 3, 4, 5, 0, {}, 4, 2, {}, 2, {1.0}, {1.0}, false}; - PathData kathy{0, 1, 16, false, 1, 2, 3, 4, 1, {}, 3, 1, {}, 1, {2.0}, {3.0}, false}; - PathData cathy{0, 3, 16, false, 1, 2, 3, 4, 1, {}, 3, 1, {}, 1, {2.0}, {3.0}, false}; + PathData pathy{0, 0, 2, 17, false, 2, 3, 4, 5, 0, {}, 4, 2, {}, 2, {1.0}, {1.0}, false}; + PathData kathy{0, 0, 1, 16, false, 1, 2, 3, 4, 1, {}, 3, 1, {}, 1, {2.0}, {3.0}, false}; + PathData cathy{0, 0, 3, 16, false, 1, 2, 3, 4, 1, {}, 3, 1, {}, 1, {2.0}, {3.0}, false}; PhantomNode node_1; PhantomNode node_2; PhantomNode node_3; diff --git a/unit_tests/library/route.cpp b/unit_tests/library/route.cpp index 44fcb877b6f..cd853f4b0f2 100644 --- a/unit_tests/library/route.cpp +++ b/unit_tests/library/route.cpp @@ -14,6 +14,12 @@ #include "osrm/osrm.hpp" #include "osrm/route_parameters.hpp" #include "osrm/status.hpp" +#include +#include +#include +#include +#include +#include osrm::Status run_route_json(const osrm::OSRM &osrm, const osrm::RouteParameters ¶ms, @@ -584,7 +590,7 @@ void test_manual_setting_of_annotations_property(bool use_json_only_api) .values["annotation"] .get() .values; - BOOST_CHECK_EQUAL(annotations.size(), 6); + BOOST_CHECK_EQUAL(annotations.size(), 7); } BOOST_AUTO_TEST_CASE(test_manual_setting_of_annotations_property_old_api) { @@ -595,6 +601,162 @@ BOOST_AUTO_TEST_CASE(test_manual_setting_of_annotations_property_new_api) test_manual_setting_of_annotations_property(false); } +using NodePair = std::pair; +using NodePairToWayIDMap = std::map; + +NodePairToWayIDMap read_node_pair_to_way_id_map(osmium::io::Reader &osm) { + struct H: public osmium::handler::Handler { + NodePairToWayIDMap ret; + void way(const osmium::Way &way) { + auto first = osmium::unsigned_object_id_type(-1); + for( const auto &n: way.nodes() ) { + const auto second = n.positive_ref(); + if( first != osmium::unsigned_object_id_type(-1) ) { + ret[{first, second}] = way.id(); + } + first = second; + } + } + } handler; + osmium::apply(osm, handler); + return std::move(handler.ret); +} + +using LonLat = std::pair; +using LonLatVector = std::vector; + +LonLatVector check_route_annotated_ways( + std::vector &coordinates, + osrm::OSRM &osrm, + NodePairToWayIDMap &node_pair_to_way_id_map, + bool use_steps +) { + LonLatVector ret; + using namespace osrm; + (void) node_pair_to_way_id_map; + RouteParameters params{}; + params.annotations_type = + RouteParameters::AnnotationsType::Nodes | + RouteParameters::AnnotationsType::Ways; + params.steps = use_steps; + params.geometries = engine::api::RouteParameters::GeometriesType::GeoJSON; + params.coordinates = coordinates; + + json::Object json_result; + const auto rc = run_route_json(osrm, params, json_result, true); + BOOST_CHECK(rc == Status::Ok); + + const auto code = json_result.values.at("code").get().value; + BOOST_CHECK_EQUAL(code, "Ok"); + + auto routes = json_result.values["routes"] + .get() + .values; + BOOST_CHECK_EQUAL(routes.size(), 1); + auto route = routes[0]; + + auto geom = route.get() + .values["geometry"] + .get() + .values["coordinates"] + .get() + .values; + + auto legs = route.get() + .values["legs"] + .get() + .values; + for(auto leg: legs) { + if( use_steps ) { + auto steps = leg.get() + .values["steps"] + .get() + .values; + for(auto step: steps) { + auto geom = step.get() + .values["geometry"] + .get() + .values["coordinates"] + .get() + .values; + for(auto gleg: geom) { + auto p = gleg.get().values; + auto lon = p[0].get().value; + auto lat = p[1].get().value; + ret.push_back(LonLat{lon, lat}); + } + } + } + auto annotations = leg.get() + .values["annotation"] + .get() + .values; + BOOST_CHECK_EQUAL(annotations.size(), 2); + + auto nodes = annotations["nodes"] + .get() + .values; + auto ways = annotations["ways"] + .get() + .values; + + BOOST_CHECK_GT(nodes.size(), 1); + BOOST_CHECK_EQUAL(nodes.size() - 1, ways.size()); + auto nodes_it = nodes.cbegin(); + auto ways_it = ways.cbegin(); + osmium::unsigned_object_id_type first = nodes_it->get().value; + for(nodes_it++; nodes_it != nodes.cend(); nodes_it++, ways_it++) { + osmium::unsigned_object_id_type second = nodes_it->get().value; + osmium::unsigned_object_id_type way_id = ways_it->get().value; + auto found = node_pair_to_way_id_map.find(NodePair(first, second)); + if( found == node_pair_to_way_id_map.end() ) + found = node_pair_to_way_id_map.find(NodePair(second, first)); + BOOST_CHECK_MESSAGE( + found != node_pair_to_way_id_map.end(), + "The node pair not found: " << first << "<->" << second + ); + BOOST_CHECK_MESSAGE( + found->second == way_id, + "The node pair way doesn't correspond: " << first << "<->" << second << "=" << found->second << "=?=" << way_id + ); + first = second; + } + } + return ret; +} + +BOOST_AUTO_TEST_CASE(test_route_annotated_ways) +{ + auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/ch/monaco.osrm"); + osmium::io::Reader osm(OSRM_TEST_DATA_DIR "/monaco.osm.pbf"); + NodePairToWayIDMap node_pair_to_way_id_map = read_node_pair_to_way_id_map(osm); + + auto coordinates = get_split_trace_locations(); + BOOST_TEST_MESSAGE("split_trace_locations without steps"); + check_route_annotated_ways(coordinates, osrm, node_pair_to_way_id_map, false); + BOOST_TEST_MESSAGE("split_trace_locations with steps"); + check_route_annotated_ways(coordinates, osrm, node_pair_to_way_id_map, true); + coordinates = get_locations_in_big_component(); + // auto coords = + BOOST_TEST_MESSAGE("locations_in_big_component without steps"); + check_route_annotated_ways(coordinates, osrm, node_pair_to_way_id_map, false); + BOOST_TEST_MESSAGE("locations_in_big_component with steps"); + auto coords = check_route_annotated_ways(coordinates, osrm, node_pair_to_way_id_map, true); + auto c1 = coords.cbegin(), c2 = coords.cend(); + for( c1++, c2--; c1 != coords.cend() && c2 != coords.cbegin(); c1++, c2--) { + if( c1 == c2 ) + continue; + coordinates = Locations{{Longitude{c1->first},Latitude{c1->second}},{Longitude{c2->first},Latitude{c2->second}}}; + BOOST_TEST_MESSAGE( + "Checking: <" << + osrm::util::toFloating(coordinates[0].lat) << ":" << osrm::util::toFloating(coordinates[0].lon) << "> -> <" << + osrm::util::toFloating(coordinates[1].lat) << ":" << osrm::util::toFloating(coordinates[1].lon) << ">" + ); + check_route_annotated_ways(coordinates, osrm, node_pair_to_way_id_map, false); + check_route_annotated_ways(coordinates, osrm, node_pair_to_way_id_map, true); + } +} + BOOST_AUTO_TEST_CASE(test_route_serialize_fb) { auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/ch/monaco.osrm"); From d69d0c2fe6ead467497e7fe91be42677dfbca519 Mon Sep 17 00:00:00 2001 From: Vsevolod Novikov Date: Mon, 15 Feb 2021 19:40:35 +0300 Subject: [PATCH 03/10] #5325 Documentation changes and some fix for flatbuffers --- docs/http.md | 8 ++++-- docs/nodejs/api.md | 6 ++-- .../api/flatbuffers/fbresult_generated.h | 28 +++++++++---------- include/engine/api/flatbuffers/route.fbs | 4 +-- include/engine/api/route_api.hpp | 4 +-- 5 files changed, 26 insertions(+), 24 deletions(-) diff --git a/docs/http.md b/docs/http.md index 398aba1aecf..58d0cd6ef61 100644 --- a/docs/http.md +++ b/docs/http.md @@ -208,7 +208,7 @@ In addition to the [general options](#general-options) the following options are |------------|---------------------------------------------|-------------------------------------------------------------------------------| |alternatives|`true`, `false` (default), or Number |Search for alternative routes. Passing a number `alternatives=n` searches for up to `n` alternative routes.\* | |steps |`true`, `false` (default) |Returned route steps for each route leg | -|annotations |`true`, `false` (default), `nodes`, `distance`, `duration`, `datasources`, `weight`, `speed` |Returns additional metadata for each coordinate along the route geometry. | +|annotations |`true`, `false` (default), `nodes`, `ways`, `distance`, `duration`, `datasources`, `weight`, `speed` |Returns additional metadata for each coordinate along the route geometry. | |geometries |`polyline` (default), `polyline6`, `geojson` |Returned route geometry format (influences overview and per step) | |overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.| |continue\_straight |`default` (default), `true`, `false` |Forces the route to keep going straight at waypoints constraining uturns there even if it would be faster. Default value depends on the profile. | @@ -430,7 +430,7 @@ In addition to the [general options](#general-options) the following options are |------------|------------------------------------------------|------------------------------------------------------------------------------------------| |steps |`true`, `false` (default) |Returned route steps for each route | |geometries |`polyline` (default), `polyline6`, `geojson` |Returned route geometry format (influences overview and per step) | -|annotations |`true`, `false` (default), `nodes`, `distance`, `duration`, `datasources`, `weight`, `speed` |Returns additional metadata for each coordinate along the route geometry. | +|annotations |`true`, `false` (default), `nodes`, `ways`, `distance`, `duration`, `datasources`, `weight`, `speed` |Returns additional metadata for each coordinate along the route geometry. | |overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.| |timestamps |`{timestamp};{timestamp}[;{timestamp} ...]` |Timestamps for the input locations in seconds since UNIX epoch. Timestamps need to be monotonically increasing. | |radiuses |`{radius};{radius}[;{radius} ...]` |Standard deviation of GPS precision used for map matching. If applicable use GPS accuracy.| @@ -486,7 +486,7 @@ In addition to the [general options](#general-options) the following options are |source |`any` (default), `first` |Returned route starts at `any` or `first` coordinate | |destination |`any` (default), `last` |Returned route ends at `any` or `last` coordinate | |steps |`true`, `false` (default) |Returned route instructions for each trip | -|annotations |`true`, `false` (default), `nodes`, `distance`, `duration`, `datasources`, `weight`, `speed` |Returns additional metadata for each coordinate along the route geometry. | +|annotations |`true`, `false` (default), `nodes`, `ways`, `distance`, `duration`, `datasources`, `weight`, `speed` |Returns additional metadata for each coordinate along the route geometry. | |geometries |`polyline` (default), `polyline6`, `geojson` |Returned route geometry format (influences overview and per step) | |overview |`simplified` (default), `full`, `false` |Add overview geometry either full, simplified according to highest zoom level it could be display on, or not at all.| @@ -700,6 +700,7 @@ Annotation of the whole route leg with fine-grained information about each segme - `duration`: The duration between each pair of coordinates, in seconds. Does not include the duration of any turns. - `datasources`: The index of the datasource for the speed between each pair of coordinates. `0` is the default profile, other values are supplied via `--segment-speed-file` to `osrm-contract` or `osrm-customize`. String-like names are in the `metadata.datasource_names` array. - `nodes`: The OSM node ID for each coordinate along the route, excluding the first/last user-supplied coordinates +- `ways`: The OSM way ID for each pair of neighbour nodes in the list of nodes - `weight`: The weights between each pair of coordinates. Does not include any turn costs. - `speed`: Convenience field, calculation of `distance / duration` rounded to one decimal place - `metadata`: Metadata related to other annotations @@ -714,6 +715,7 @@ Annotation of the whole route leg with fine-grained information about each segme "datasources": [1,0,0,0,1], "metadata": { "datasource_names": ["traffic","lua profile","lua profile","lua profile","traffic"] }, "nodes": [49772551,49772552,49786799,49786800,49786801,49786802], + "ways": [130764281,130764281,6056749,6056749,6056749], "weight": [15,15,40,15,15] } ``` diff --git a/docs/nodejs/api.md b/docs/nodejs/api.md index 9bff3ada8c6..a06ed047067 100644 --- a/docs/nodejs/api.md +++ b/docs/nodejs/api.md @@ -55,7 +55,7 @@ Returns the fastest route between two or more coordinates while visiting the way - `options.alternatives` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Search for up to this many alternative routes. _Please note that even if alternative routes are requested, a result cannot be guaranteed._ (optional, default `0`) - `options.steps` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Return route steps for each route leg. (optional, default `false`) - - `options.annotations` **([Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean))** An array with strings of `duration`, `nodes`, `distance`, `weight`, `datasources`, `speed` or boolean for enabling/disabling all. (optional, default `false`) + - `options.annotations` **([Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean))** An array with strings of `duration`, `nodes`, `ways`, `distance`, `weight`, `datasources`, `speed` or boolean for enabling/disabling all. (optional, default `false`) - `options.geometries` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Returned route geometry format (influences overview and per step). Can also be `geojson`. (optional, default `polyline`) - `options.overview` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Add overview geometry either `full`, `simplified` according to highest zoom level it could be display on, or not at all (`false`). (optional, default `simplified`) - `options.continue_straight` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Forces the route to keep going straight at waypoints and don't do a uturn even if it would be faster. Default value depends on the profile. @@ -215,7 +215,7 @@ if they can not be matched successfully. - `options.hints` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Hints for the coordinate snapping. Array of base64 encoded strings. - `options.generate_hints` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Whether or not adds a Hint to the response which can be used in subsequent requests. (optional, default `true`) - `options.steps` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Return route steps for each route. (optional, default `false`) - - `options.annotations` **([Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean))** An array with strings of `duration`, `nodes`, `distance`, `weight`, `datasources`, `speed` or boolean for enabling/disabling all. (optional, default `false`) + - `options.annotations` **([Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean))** An array with strings of `duration`, `nodes`, `ways`, `distance`, `weight`, `datasources`, `speed` or boolean for enabling/disabling all. (optional, default `false`) - `options.geometries` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Returned route geometry format (influences overview and per step). Can also be `geojson`. (optional, default `polyline`) - `options.overview` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Add overview geometry either `full`, `simplified` according to highest zoom level it could be display on, or not at all (`false`). (optional, default `simplified`) - `options.timestamps` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)<[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)>?** Timestamp of the input location (integers, UNIX-like timestamp). @@ -282,7 +282,7 @@ Right now, the following combinations are possible: - `options.hints` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)?** Hints for the coordinate snapping. Array of base64 encoded strings. - `options.generate_hints` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)?** Whether or not adds a Hint to the response which can be used in subsequent requests. (optional, default `true`) - `options.steps` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Return route steps for each route. (optional, default `false`) - - `options.annotations` **([Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean))** An array with strings of `duration`, `nodes`, `distance`, `weight`, `datasources`, `speed` or boolean for enabling/disabling all. (optional, default `false`) + - `options.annotations` **([Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) \| [Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean))** An array with strings of `duration`, `nodes`, `ways`, `distance`, `weight`, `datasources`, `speed` or boolean for enabling/disabling all. (optional, default `false`) - `options.geometries` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Returned route geometry format (influences overview and per step). Can also be `geojson`. (optional, default `polyline`) - `options.overview` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** Add overview geometry either `full`, `simplified` (optional, default `simplified`) - `options.roundtrip` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Return route is a roundtrip. (optional, default `true`) diff --git a/include/engine/api/flatbuffers/fbresult_generated.h b/include/engine/api/flatbuffers/fbresult_generated.h index 28198e0fb65..ce09bf4d63e 100644 --- a/include/engine/api/flatbuffers/fbresult_generated.h +++ b/include/engine/api/flatbuffers/fbresult_generated.h @@ -461,8 +461,8 @@ struct AnnotationT : public flatbuffers::NativeTable { std::vector distance; std::vector duration; std::vector datasources; - std::vector nodes; - std::vector ways; + std::vector nodes; + std::vector ways; std::vector weight; std::vector speed; std::unique_ptr metadata; @@ -491,11 +491,11 @@ struct Annotation FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { const flatbuffers::Vector *datasources() const { return GetPointer *>(VT_DATASOURCES); } - const flatbuffers::Vector *nodes() const { - return GetPointer *>(VT_NODES); + const flatbuffers::Vector *nodes() const { + return GetPointer *>(VT_NODES); } - const flatbuffers::Vector *ways() const { - return GetPointer *>(VT_WAYS); + const flatbuffers::Vector *ways() const { + return GetPointer *>(VT_WAYS); } const flatbuffers::Vector *weight() const { return GetPointer *>(VT_WEIGHT); @@ -543,10 +543,10 @@ struct AnnotationBuilder { void add_datasources(flatbuffers::Offset> datasources) { fbb_.AddOffset(Annotation::VT_DATASOURCES, datasources); } - void add_nodes(flatbuffers::Offset> nodes) { + void add_nodes(flatbuffers::Offset> nodes) { fbb_.AddOffset(Annotation::VT_NODES, nodes); } - void add_ways(flatbuffers::Offset> ways) { + void add_ways(flatbuffers::Offset> ways) { fbb_.AddOffset(Annotation::VT_WAYS, ways); } void add_weight(flatbuffers::Offset> weight) { @@ -575,8 +575,8 @@ inline flatbuffers::Offset CreateAnnotation( flatbuffers::Offset> distance = 0, flatbuffers::Offset> duration = 0, flatbuffers::Offset> datasources = 0, - flatbuffers::Offset> nodes = 0, - flatbuffers::Offset> ways = 0, + flatbuffers::Offset> nodes = 0, + flatbuffers::Offset> ways = 0, flatbuffers::Offset> weight = 0, flatbuffers::Offset> speed = 0, flatbuffers::Offset metadata = 0) { @@ -597,16 +597,16 @@ inline flatbuffers::Offset CreateAnnotationDirect( const std::vector *distance = nullptr, const std::vector *duration = nullptr, const std::vector *datasources = nullptr, - const std::vector *nodes = nullptr, - const std::vector *ways = nullptr, + const std::vector *nodes = nullptr, + const std::vector *ways = nullptr, const std::vector *weight = nullptr, const std::vector *speed = nullptr, flatbuffers::Offset metadata = 0) { auto distance__ = distance ? _fbb.CreateVector(*distance) : 0; auto duration__ = duration ? _fbb.CreateVector(*duration) : 0; auto datasources__ = datasources ? _fbb.CreateVector(*datasources) : 0; - auto nodes__ = nodes ? _fbb.CreateVector(*nodes) : 0; - auto ways__ = ways ? _fbb.CreateVector(*ways) : 0; + auto nodes__ = nodes ? _fbb.CreateVector(*nodes) : 0; + auto ways__ = ways ? _fbb.CreateVector(*ways) : 0; auto weight__ = weight ? _fbb.CreateVector(*weight) : 0; auto speed__ = speed ? _fbb.CreateVector(*speed) : 0; return osrm::engine::api::fbresult::CreateAnnotation( diff --git a/include/engine/api/flatbuffers/route.fbs b/include/engine/api/flatbuffers/route.fbs index f826d5787f9..8b15429589c 100644 --- a/include/engine/api/flatbuffers/route.fbs +++ b/include/engine/api/flatbuffers/route.fbs @@ -9,8 +9,8 @@ table Annotation { distance: [uint]; duration: [uint]; datasources: [uint]; - nodes: [uint]; - ways: [uint]; + nodes: [ulong]; + ways: [ulong]; weight: [uint]; speed: [float]; metadata: Metadata; diff --git a/include/engine/api/route_api.hpp b/include/engine/api/route_api.hpp index e1d4ae59762..7376e6b0f7d 100644 --- a/include/engine/api/route_api.hpp +++ b/include/engine/api/route_api.hpp @@ -494,7 +494,7 @@ class RouteAPI : public BaseAPI return anno.datasource; }); } - std::vector nodes; + std::vector nodes; if (requested_annotations & RouteParameters::AnnotationsType::Nodes) { nodes.reserve(leg_geometry.osm_node_ids.size()); @@ -503,7 +503,7 @@ class RouteAPI : public BaseAPI nodes.emplace_back(static_cast(node_id)); } } - std::vector ways; + std::vector ways; if (requested_annotations & RouteParameters::AnnotationsType::Ways) { ways.reserve(leg_geometry.osm_way_ids.size()); From 44bc0a521eae7e304ccfa8626de61e54bfe72ebc Mon Sep 17 00:00:00 2001 From: Vsevolod Novikov Date: Mon, 15 Feb 2021 19:46:06 +0300 Subject: [PATCH 04/10] #5325 CLang format --- include/engine/guidance/assemble_geometry.hpp | 2 +- .../extractor/compressed_edge_container.hpp | 5 +- include/extractor/node_based_edge.hpp | 2 +- .../server/api/route_parameters_grammar.hpp | 6 +- src/engine/guidance/post_processing.cpp | 2 +- src/extractor/compressed_edge_container.cpp | 54 ++++--- src/extractor/extractor.cpp | 18 ++- src/extractor/extractor_callbacks.cpp | 3 +- src/extractor/node_based_graph_factory.cpp | 3 +- unit_tests/library/route.cpp | 138 +++++++++--------- 10 files changed, 123 insertions(+), 110 deletions(-) diff --git a/include/engine/guidance/assemble_geometry.hpp b/include/engine/guidance/assemble_geometry.hpp index b651fbd07fb..a9623c20998 100644 --- a/include/engine/guidance/assemble_geometry.hpp +++ b/include/engine/guidance/assemble_geometry.hpp @@ -56,7 +56,7 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade, reversed_source ? source_node.reverse_segment_id.id : source_node.forward_segment_id.id; const auto source_geometry_id = facade.GetGeometryIndex(source_node_id).id; const auto source_geometry = facade.GetUncompressedForwardGeometry(source_geometry_id); - //const auto source_osm_way_ids = facade.GetUncompressedForwardWayIDs(source_geometry_id); + // const auto source_osm_way_ids = facade.GetUncompressedForwardWayIDs(source_geometry_id); geometry.osm_node_ids.push_back( facade.GetOSMNodeIDOfNode(source_geometry(source_segment_start_coordinate))); diff --git a/include/extractor/compressed_edge_container.hpp b/include/extractor/compressed_edge_container.hpp index 904369b0e95..7412d7606f9 100644 --- a/include/extractor/compressed_edge_container.hpp +++ b/include/extractor/compressed_edge_container.hpp @@ -1,8 +1,8 @@ #ifndef GEOMETRY_COMPRESSOR_HPP_ #define GEOMETRY_COMPRESSOR_HPP_ -#include "extractor/segment_data_container.hpp" #include "extractor/node_based_edge.hpp" +#include "extractor/segment_data_container.hpp" #include "util/typedefs.hpp" @@ -49,7 +49,8 @@ class CompressedEdgeContainer const SegmentWeight duration); void InitializeBothwayVector(); - unsigned ZipEdges(const unsigned f_edge_pos, const unsigned r_edge_pos, OSMWayIDMap &osm_way_id_map); + unsigned + ZipEdges(const unsigned f_edge_pos, const unsigned r_edge_pos, OSMWayIDMap &osm_way_id_map); bool HasEntryForID(const EdgeID edge_id) const; bool HasZippedEntryForForwardID(const EdgeID edge_id) const; diff --git a/include/extractor/node_based_edge.hpp b/include/extractor/node_based_edge.hpp index 44f198da74e..09148422a15 100644 --- a/include/extractor/node_based_edge.hpp +++ b/include/extractor/node_based_edge.hpp @@ -2,8 +2,8 @@ #define NODE_BASED_EDGE_HPP #include -#include #include +#include #include "extractor/class_data.hpp" #include "extractor/travel_mode.hpp" diff --git a/include/server/api/route_parameters_grammar.hpp b/include/server/api/route_parameters_grammar.hpp index dc005043b8f..653ed5df750 100644 --- a/include/server/api/route_parameters_grammar.hpp +++ b/include/server/api/route_parameters_grammar.hpp @@ -73,10 +73,8 @@ struct RouteParametersGrammar : public BaseParametersGrammar &steps, LegGeometry &geometry) geometry.osm_node_ids.erase(geometry.osm_node_ids.begin(), geometry.osm_node_ids.begin() + offset); geometry.osm_way_ids.erase(geometry.osm_way_ids.begin(), - geometry.osm_way_ids.begin() + offset); + geometry.osm_way_ids.begin() + offset); } auto const first_bearing = steps.front().maneuver.bearing_after; diff --git a/src/extractor/compressed_edge_container.cpp b/src/extractor/compressed_edge_container.cpp index 81b2e631c56..92db95896fc 100644 --- a/src/extractor/compressed_edge_container.cpp +++ b/src/extractor/compressed_edge_container.cpp @@ -262,7 +262,9 @@ void CompressedEdgeContainer::InitializeBothwayVector() segment_data->rev_datasources.reserve(m_compressed_oneway_geometries.size()); } -unsigned CompressedEdgeContainer::ZipEdges(const EdgeID f_edge_id, const EdgeID r_edge_id, OSMWayIDMap &osm_way_id_map) +unsigned CompressedEdgeContainer::ZipEdges(const EdgeID f_edge_id, + const EdgeID r_edge_id, + OSMWayIDMap &osm_way_id_map) { if (!segment_data) InitializeBothwayVector(); @@ -299,18 +301,27 @@ unsigned CompressedEdgeContainer::ZipEdges(const EdgeID f_edge_id, const EdgeID BOOST_ASSERT(fwd_node.node_id == rev_node.node_id); auto node_id = fwd_node.node_id; - if( node_id != prev_node_id ) { - auto find_way_id = osm_way_id_map.find( OSMWayIDMapKey(prev_node_id, node_id) ); - if( find_way_id == osm_way_id_map.cend() ) { - find_way_id = osm_way_id_map.find( OSMWayIDMapKey(node_id, prev_node_id) ); + if (node_id != prev_node_id) + { + auto find_way_id = osm_way_id_map.find(OSMWayIDMapKey(prev_node_id, node_id)); + if (find_way_id == osm_way_id_map.cend()) + { + find_way_id = osm_way_id_map.find(OSMWayIDMapKey(node_id, prev_node_id)); } - if( find_way_id == osm_way_id_map.cend() ) { - util::Log(logERROR) << "OSM Way ID not found for (nbg) nodes, it should never be happened: " << prev_node_id << "<-x->" << node_id; + if (find_way_id == osm_way_id_map.cend()) + { + util::Log(logERROR) + << "OSM Way ID not found for (nbg) nodes, it should never be happened: " + << prev_node_id << "<-x->" << node_id; segment_data->osm_ways.emplace_back(osm_way_id); - } else { + } + else + { segment_data->osm_ways.emplace_back(osm_way_id = find_way_id->second); } - } else { + } + else + { // Special case (artificial lighting signal edge) segment_data->osm_ways.emplace_back(osm_way_id); } @@ -327,18 +338,27 @@ unsigned CompressedEdgeContainer::ZipEdges(const EdgeID f_edge_id, const EdgeID const auto &last_node = forward_bucket.back(); auto node_id = last_node.node_id; - if( node_id != prev_node_id ) { - auto find_way_id = osm_way_id_map.find( OSMWayIDMapKey(prev_node_id, node_id) ); - if( find_way_id == osm_way_id_map.cend() ) { - find_way_id = osm_way_id_map.find( OSMWayIDMapKey(node_id, prev_node_id) ); + if (node_id != prev_node_id) + { + auto find_way_id = osm_way_id_map.find(OSMWayIDMapKey(prev_node_id, node_id)); + if (find_way_id == osm_way_id_map.cend()) + { + find_way_id = osm_way_id_map.find(OSMWayIDMapKey(node_id, prev_node_id)); } - if( find_way_id == osm_way_id_map.cend() ) { - util::Log(logERROR) << "OSM Way ID not found for (nbg) nodes, it should never be happened: " << prev_node_id << "<-x->" << node_id; + if (find_way_id == osm_way_id_map.cend()) + { + util::Log(logERROR) + << "OSM Way ID not found for (nbg) nodes, it should never be happened: " + << prev_node_id << "<-x->" << node_id; segment_data->osm_ways.emplace_back(osm_way_id); - } else { + } + else + { segment_data->osm_ways.emplace_back(osm_way_id = find_way_id->second); } - } else { + } + else + { // Special case (artificial lighting signal edge) segment_data->osm_ways.emplace_back(osm_way_id); } diff --git a/src/extractor/extractor.cpp b/src/extractor/extractor.cpp index 641e80b345b..eb9b6829f26 100644 --- a/src/extractor/extractor.cpp +++ b/src/extractor/extractor.cpp @@ -370,10 +370,12 @@ int Extractor::run(ScriptingEnvironment &scripting_environment) return 0; } -std:: - tuple, std::vector> - Extractor::ParseOSMData(ScriptingEnvironment &scripting_environment, - const unsigned number_of_threads) +std::tuple, + std::vector> +Extractor::ParseOSMData(ScriptingEnvironment &scripting_environment, + const unsigned number_of_threads) { TIMER_START(extracting); @@ -631,10 +633,10 @@ std:: files::writeProfileProperties(config.GetPath(".osrm.properties").string(), profile_properties); // Fill OSM Way ID Lookup Map to use it later - for(auto edge: extraction_containers.all_edges_list) { - osm_way_id_map[ - OSMWayIDMapKey(edge.result.source, edge.result.target) - ] = edge.result.osm_way_id; + for (auto edge : extraction_containers.all_edges_list) + { + osm_way_id_map[OSMWayIDMapKey(edge.result.source, edge.result.target)] = + edge.result.osm_way_id; } TIMER_STOP(extracting); diff --git a/src/extractor/extractor_callbacks.cpp b/src/extractor/extractor_callbacks.cpp index 4b6bf84e2b5..bc5f5627ad4 100644 --- a/src/extractor/extractor_callbacks.cpp +++ b/src/extractor/extractor_callbacks.cpp @@ -32,8 +32,7 @@ ExtractorCallbacks::ExtractorCallbacks(ExtractionContainers &extraction_containe OSMWayIDMap &osm_way_id_map, const ProfileProperties &properties) : external_memory(extraction_containers_), classes_map(classes_map), - lane_description_map(lane_description_map), - osm_way_id_map(osm_way_id_map), + lane_description_map(lane_description_map), osm_way_id_map(osm_way_id_map), fallback_to_duration(properties.fallback_to_duration), force_split_edges(properties.force_split_edges) { diff --git a/src/extractor/node_based_graph_factory.cpp b/src/extractor/node_based_graph_factory.cpp index 6ae8dbf9478..4ca097b467a 100644 --- a/src/extractor/node_based_graph_factory.cpp +++ b/src/extractor/node_based_graph_factory.cpp @@ -127,7 +127,8 @@ void NodeBasedGraphFactory::CompressGeometry(OSMWayIDMap &osm_way_id_map) const EdgeID edge_id_2 = compressed_output_graph.FindEdge(to, from); BOOST_ASSERT(edge_id_2 != SPECIAL_EDGEID); - auto packed_geometry_id = compressed_edge_container.ZipEdges(edge_id_1, edge_id_2, osm_way_id_map); + auto packed_geometry_id = + compressed_edge_container.ZipEdges(edge_id_1, edge_id_2, osm_way_id_map); // remember the geometry ID for both edges in the node-based graph compressed_output_graph.GetEdgeData(edge_id_1).geometry_id = {packed_geometry_id, true}; diff --git a/unit_tests/library/route.cpp b/unit_tests/library/route.cpp index cd853f4b0f2..75444061a76 100644 --- a/unit_tests/library/route.cpp +++ b/unit_tests/library/route.cpp @@ -14,9 +14,9 @@ #include "osrm/osrm.hpp" #include "osrm/route_parameters.hpp" #include "osrm/status.hpp" -#include -#include #include +#include +#include #include #include #include @@ -601,17 +601,22 @@ BOOST_AUTO_TEST_CASE(test_manual_setting_of_annotations_property_new_api) test_manual_setting_of_annotations_property(false); } -using NodePair = std::pair; -using NodePairToWayIDMap = std::map; +using NodePair = std::pair; +using NodePairToWayIDMap = std::map; -NodePairToWayIDMap read_node_pair_to_way_id_map(osmium::io::Reader &osm) { - struct H: public osmium::handler::Handler { +NodePairToWayIDMap read_node_pair_to_way_id_map(osmium::io::Reader &osm) +{ + struct H : public osmium::handler::Handler + { NodePairToWayIDMap ret; - void way(const osmium::Way &way) { + void way(const osmium::Way &way) + { auto first = osmium::unsigned_object_id_type(-1); - for( const auto &n: way.nodes() ) { + for (const auto &n : way.nodes()) + { const auto second = n.positive_ref(); - if( first != osmium::unsigned_object_id_type(-1) ) { + if (first != osmium::unsigned_object_id_type(-1)) + { ret[{first, second}] = way.id(); } first = second; @@ -625,19 +630,17 @@ NodePairToWayIDMap read_node_pair_to_way_id_map(osmium::io::Reader &osm) { using LonLat = std::pair; using LonLatVector = std::vector; -LonLatVector check_route_annotated_ways( - std::vector &coordinates, - osrm::OSRM &osrm, - NodePairToWayIDMap &node_pair_to_way_id_map, - bool use_steps -) { +LonLatVector check_route_annotated_ways(std::vector &coordinates, + osrm::OSRM &osrm, + NodePairToWayIDMap &node_pair_to_way_id_map, + bool use_steps) +{ LonLatVector ret; using namespace osrm; - (void) node_pair_to_way_id_map; + (void)node_pair_to_way_id_map; RouteParameters params{}; params.annotations_type = - RouteParameters::AnnotationsType::Nodes | - RouteParameters::AnnotationsType::Ways; + RouteParameters::AnnotationsType::Nodes | RouteParameters::AnnotationsType::Ways; params.steps = use_steps; params.geometries = engine::api::RouteParameters::GeometriesType::GeoJSON; params.coordinates = coordinates; @@ -649,37 +652,33 @@ LonLatVector check_route_annotated_ways( const auto code = json_result.values.at("code").get().value; BOOST_CHECK_EQUAL(code, "Ok"); - auto routes = json_result.values["routes"] - .get() - .values; + auto routes = json_result.values["routes"].get().values; BOOST_CHECK_EQUAL(routes.size(), 1); auto route = routes[0]; auto geom = route.get() - .values["geometry"] - .get() - .values["coordinates"] - .get() - .values; - - auto legs = route.get() - .values["legs"] - .get() - .values; - for(auto leg: legs) { - if( use_steps ) { - auto steps = leg.get() - .values["steps"] - .get() - .values; - for(auto step: steps) { + .values["geometry"] + .get() + .values["coordinates"] + .get() + .values; + + auto legs = route.get().values["legs"].get().values; + for (auto leg : legs) + { + if (use_steps) + { + auto steps = leg.get().values["steps"].get().values; + for (auto step : steps) + { auto geom = step.get() - .values["geometry"] - .get() - .values["coordinates"] - .get() - .values; - for(auto gleg: geom) { + .values["geometry"] + .get() + .values["coordinates"] + .get() + .values; + for (auto gleg : geom) + { auto p = gleg.get().values; auto lon = p[0].get().value; auto lat = p[1].get().value; @@ -687,38 +686,30 @@ LonLatVector check_route_annotated_ways( } } } - auto annotations = leg.get() - .values["annotation"] - .get() - .values; + auto annotations = leg.get().values["annotation"].get().values; BOOST_CHECK_EQUAL(annotations.size(), 2); - auto nodes = annotations["nodes"] - .get() - .values; - auto ways = annotations["ways"] - .get() - .values; + auto nodes = annotations["nodes"].get().values; + auto ways = annotations["ways"].get().values; BOOST_CHECK_GT(nodes.size(), 1); BOOST_CHECK_EQUAL(nodes.size() - 1, ways.size()); auto nodes_it = nodes.cbegin(); auto ways_it = ways.cbegin(); osmium::unsigned_object_id_type first = nodes_it->get().value; - for(nodes_it++; nodes_it != nodes.cend(); nodes_it++, ways_it++) { + for (nodes_it++; nodes_it != nodes.cend(); nodes_it++, ways_it++) + { osmium::unsigned_object_id_type second = nodes_it->get().value; osmium::unsigned_object_id_type way_id = ways_it->get().value; auto found = node_pair_to_way_id_map.find(NodePair(first, second)); - if( found == node_pair_to_way_id_map.end() ) + if (found == node_pair_to_way_id_map.end()) found = node_pair_to_way_id_map.find(NodePair(second, first)); - BOOST_CHECK_MESSAGE( - found != node_pair_to_way_id_map.end(), - "The node pair not found: " << first << "<->" << second - ); - BOOST_CHECK_MESSAGE( - found->second == way_id, - "The node pair way doesn't correspond: " << first << "<->" << second << "=" << found->second << "=?=" << way_id - ); + BOOST_CHECK_MESSAGE(found != node_pair_to_way_id_map.end(), + "The node pair not found: " << first << "<->" << second); + BOOST_CHECK_MESSAGE(found->second == way_id, + "The node pair way doesn't correspond: " << first << "<->" << second + << "=" << found->second + << "=?=" << way_id); first = second; } } @@ -737,21 +728,22 @@ BOOST_AUTO_TEST_CASE(test_route_annotated_ways) BOOST_TEST_MESSAGE("split_trace_locations with steps"); check_route_annotated_ways(coordinates, osrm, node_pair_to_way_id_map, true); coordinates = get_locations_in_big_component(); - // auto coords = + // auto coords = BOOST_TEST_MESSAGE("locations_in_big_component without steps"); check_route_annotated_ways(coordinates, osrm, node_pair_to_way_id_map, false); BOOST_TEST_MESSAGE("locations_in_big_component with steps"); auto coords = check_route_annotated_ways(coordinates, osrm, node_pair_to_way_id_map, true); auto c1 = coords.cbegin(), c2 = coords.cend(); - for( c1++, c2--; c1 != coords.cend() && c2 != coords.cbegin(); c1++, c2--) { - if( c1 == c2 ) + for (c1++, c2--; c1 != coords.cend() && c2 != coords.cbegin(); c1++, c2--) + { + if (c1 == c2) continue; - coordinates = Locations{{Longitude{c1->first},Latitude{c1->second}},{Longitude{c2->first},Latitude{c2->second}}}; - BOOST_TEST_MESSAGE( - "Checking: <" << - osrm::util::toFloating(coordinates[0].lat) << ":" << osrm::util::toFloating(coordinates[0].lon) << "> -> <" << - osrm::util::toFloating(coordinates[1].lat) << ":" << osrm::util::toFloating(coordinates[1].lon) << ">" - ); + coordinates = Locations{{Longitude{c1->first}, Latitude{c1->second}}, + {Longitude{c2->first}, Latitude{c2->second}}}; + BOOST_TEST_MESSAGE("Checking: <" << osrm::util::toFloating(coordinates[0].lat) << ":" + << osrm::util::toFloating(coordinates[0].lon) << "> -> <" + << osrm::util::toFloating(coordinates[1].lat) << ":" + << osrm::util::toFloating(coordinates[1].lon) << ">"); check_route_annotated_ways(coordinates, osrm, node_pair_to_way_id_map, false); check_route_annotated_ways(coordinates, osrm, node_pair_to_way_id_map, true); } From d946025f39d0001486112581454ff22e46d342e1 Mon Sep 17 00:00:00 2001 From: Vsevolod Novikov Date: Mon, 22 Feb 2021 22:14:08 +0300 Subject: [PATCH 05/10] #5325 Return way ID with sign meaning direction --- docs/http.md | 4 +-- .../api/flatbuffers/fbresult_generated.h | 14 +++++----- include/engine/api/flatbuffers/route.fbs | 2 +- include/engine/api/route_api.hpp | 6 ++-- include/engine/datafacade/datafacade_base.hpp | 4 ++- include/engine/guidance/assemble_geometry.hpp | 13 +++++++-- include/engine/guidance/leg_geometry.hpp | 2 +- include/engine/internal_route_result.hpp | 2 +- .../routing_algorithms/routing_base.hpp | 2 +- include/extractor/node_based_edge.hpp | 2 +- include/extractor/segment_data_container.hpp | 12 ++++++-- include/storage/view_factory.hpp | 2 +- include/util/typedefs.hpp | 1 + src/extractor/compressed_edge_container.cpp | 26 ++++++++--------- src/extractor/extractor.cpp | 28 +++++++++++++++++-- unit_tests/library/route.cpp | 17 +++++++---- unit_tests/mocks/mock_datafacade.hpp | 2 +- 17 files changed, 91 insertions(+), 48 deletions(-) diff --git a/docs/http.md b/docs/http.md index 58d0cd6ef61..18dcaae5ef5 100644 --- a/docs/http.md +++ b/docs/http.md @@ -700,7 +700,7 @@ Annotation of the whole route leg with fine-grained information about each segme - `duration`: The duration between each pair of coordinates, in seconds. Does not include the duration of any turns. - `datasources`: The index of the datasource for the speed between each pair of coordinates. `0` is the default profile, other values are supplied via `--segment-speed-file` to `osrm-contract` or `osrm-customize`. String-like names are in the `metadata.datasource_names` array. - `nodes`: The OSM node ID for each coordinate along the route, excluding the first/last user-supplied coordinates -- `ways`: The OSM way ID for each pair of neighbour nodes in the list of nodes +- `ways`: The OSM way ID for each pair of neighbor nodes in the list of nodes, with a sign. The sign means direction. A positive sign means moving in the direction of the way, while negative means moving in the opposite direction. - `weight`: The weights between each pair of coordinates. Does not include any turn costs. - `speed`: Convenience field, calculation of `distance / duration` rounded to one decimal place - `metadata`: Metadata related to other annotations @@ -715,7 +715,7 @@ Annotation of the whole route leg with fine-grained information about each segme "datasources": [1,0,0,0,1], "metadata": { "datasource_names": ["traffic","lua profile","lua profile","lua profile","traffic"] }, "nodes": [49772551,49772552,49786799,49786800,49786801,49786802], - "ways": [130764281,130764281,6056749,6056749,6056749], + "ways": [130764281,130764281,-6056749,-6056749,-6056749], "weight": [15,15,40,15,15] } ``` diff --git a/include/engine/api/flatbuffers/fbresult_generated.h b/include/engine/api/flatbuffers/fbresult_generated.h index ce09bf4d63e..a71d1ef7e1d 100644 --- a/include/engine/api/flatbuffers/fbresult_generated.h +++ b/include/engine/api/flatbuffers/fbresult_generated.h @@ -462,7 +462,7 @@ struct AnnotationT : public flatbuffers::NativeTable { std::vector duration; std::vector datasources; std::vector nodes; - std::vector ways; + std::vector ways; std::vector weight; std::vector speed; std::unique_ptr metadata; @@ -494,8 +494,8 @@ struct Annotation FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { const flatbuffers::Vector *nodes() const { return GetPointer *>(VT_NODES); } - const flatbuffers::Vector *ways() const { - return GetPointer *>(VT_WAYS); + const flatbuffers::Vector *ways() const { + return GetPointer *>(VT_WAYS); } const flatbuffers::Vector *weight() const { return GetPointer *>(VT_WEIGHT); @@ -546,7 +546,7 @@ struct AnnotationBuilder { void add_nodes(flatbuffers::Offset> nodes) { fbb_.AddOffset(Annotation::VT_NODES, nodes); } - void add_ways(flatbuffers::Offset> ways) { + void add_ways(flatbuffers::Offset> ways) { fbb_.AddOffset(Annotation::VT_WAYS, ways); } void add_weight(flatbuffers::Offset> weight) { @@ -576,7 +576,7 @@ inline flatbuffers::Offset CreateAnnotation( flatbuffers::Offset> duration = 0, flatbuffers::Offset> datasources = 0, flatbuffers::Offset> nodes = 0, - flatbuffers::Offset> ways = 0, + flatbuffers::Offset> ways = 0, flatbuffers::Offset> weight = 0, flatbuffers::Offset> speed = 0, flatbuffers::Offset metadata = 0) { @@ -598,7 +598,7 @@ inline flatbuffers::Offset CreateAnnotationDirect( const std::vector *duration = nullptr, const std::vector *datasources = nullptr, const std::vector *nodes = nullptr, - const std::vector *ways = nullptr, + const std::vector *ways = nullptr, const std::vector *weight = nullptr, const std::vector *speed = nullptr, flatbuffers::Offset metadata = 0) { @@ -606,7 +606,7 @@ inline flatbuffers::Offset CreateAnnotationDirect( auto duration__ = duration ? _fbb.CreateVector(*duration) : 0; auto datasources__ = datasources ? _fbb.CreateVector(*datasources) : 0; auto nodes__ = nodes ? _fbb.CreateVector(*nodes) : 0; - auto ways__ = ways ? _fbb.CreateVector(*ways) : 0; + auto ways__ = ways ? _fbb.CreateVector(*ways) : 0; auto weight__ = weight ? _fbb.CreateVector(*weight) : 0; auto speed__ = speed ? _fbb.CreateVector(*speed) : 0; return osrm::engine::api::fbresult::CreateAnnotation( diff --git a/include/engine/api/flatbuffers/route.fbs b/include/engine/api/flatbuffers/route.fbs index 8b15429589c..bfd69383d66 100644 --- a/include/engine/api/flatbuffers/route.fbs +++ b/include/engine/api/flatbuffers/route.fbs @@ -10,7 +10,7 @@ table Annotation { duration: [uint]; datasources: [uint]; nodes: [ulong]; - ways: [ulong]; + ways: [long]; weight: [uint]; speed: [float]; metadata: Metadata; diff --git a/include/engine/api/route_api.hpp b/include/engine/api/route_api.hpp index 7376e6b0f7d..dadc1244249 100644 --- a/include/engine/api/route_api.hpp +++ b/include/engine/api/route_api.hpp @@ -503,13 +503,13 @@ class RouteAPI : public BaseAPI nodes.emplace_back(static_cast(node_id)); } } - std::vector ways; + std::vector ways; if (requested_annotations & RouteParameters::AnnotationsType::Ways) { ways.reserve(leg_geometry.osm_way_ids.size()); for (const auto way_id : leg_geometry.osm_way_ids) { - ways.emplace_back(static_cast(way_id)); + ways.emplace_back(static_cast(way_id)); } } auto nodes_vector = fb_result.CreateVector(nodes); @@ -849,7 +849,7 @@ class RouteAPI : public BaseAPI ways.values.reserve(leg_geometry.osm_way_ids.size()); for (const auto way_id : leg_geometry.osm_way_ids) { - ways.values.push_back(static_cast(way_id)); + ways.values.push_back(static_cast(way_id)); } annotation.values["ways"] = std::move(ways); } diff --git a/include/engine/datafacade/datafacade_base.hpp b/include/engine/datafacade/datafacade_base.hpp index 839138643d3..3b5a998f3a0 100644 --- a/include/engine/datafacade/datafacade_base.hpp +++ b/include/engine/datafacade/datafacade_base.hpp @@ -59,7 +59,9 @@ class BaseDataFacade using OSMWayForwardRange = boost::iterator_range; - using OSMWayReverseRange = boost::reversed_range; + using OSMWayNegateForwardRange = + boost::transformed_range, const OSMWayForwardRange>; + using OSMWayReverseRange = boost::reversed_range; using WeightForwardRange = boost::iterator_range; diff --git a/include/engine/guidance/assemble_geometry.hpp b/include/engine/guidance/assemble_geometry.hpp index a9623c20998..b4e5028fb58 100644 --- a/include/engine/guidance/assemble_geometry.hpp +++ b/include/engine/guidance/assemble_geometry.hpp @@ -161,10 +161,19 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade, const auto target_segment_end_coordinate = target_node.fwd_segment_position + (reversed_target ? 0 : 1); const auto target_geometry = facade.GetUncompressedForwardGeometry(target_geometry_id); - const auto target_osm_way_ids = facade.GetUncompressedForwardWayIDs(target_geometry_id); geometry.osm_node_ids.push_back( facade.GetOSMNodeIDOfNode(target_geometry(target_segment_end_coordinate))); - geometry.osm_way_ids.push_back(target_osm_way_ids(target_node.fwd_segment_position)); + if (reversed_target) + { + const auto target_osm_way_ids = facade.GetUncompressedReverseWayIDs(target_geometry_id); + geometry.osm_way_ids.push_back( + target_osm_way_ids(target_osm_way_ids.size() - target_node.fwd_segment_position - 1)); + } + else + { + const auto target_osm_way_ids = facade.GetUncompressedForwardWayIDs(target_geometry_id); + geometry.osm_way_ids.push_back(target_osm_way_ids(target_node.fwd_segment_position)); + } BOOST_ASSERT(geometry.segment_distances.size() == geometry.segment_offsets.size() - 1); BOOST_ASSERT(geometry.locations.size() > geometry.segment_distances.size()); diff --git a/include/engine/guidance/leg_geometry.hpp b/include/engine/guidance/leg_geometry.hpp index daccff8fcef..ebbc056e13f 100644 --- a/include/engine/guidance/leg_geometry.hpp +++ b/include/engine/guidance/leg_geometry.hpp @@ -34,7 +34,7 @@ struct LegGeometry // original OSM node IDs for each coordinate std::vector osm_node_ids; // original OSM way IDs between every pair of nodes - std::vector osm_way_ids; + std::vector osm_way_ids; // Per-coordinate metadata struct Annotation diff --git a/include/engine/internal_route_result.hpp b/include/engine/internal_route_result.hpp index 6c7193dc504..c33fb98c022 100644 --- a/include/engine/internal_route_result.hpp +++ b/include/engine/internal_route_result.hpp @@ -27,7 +27,7 @@ struct PathData // from edge-based-node id NodeID from_edge_based_node; // OSM Way ID of the edge immediately followed by via node - OSMWayID osm_way_id; + OSMWayIDDir osm_way_id; // the internal OSRM id of the OSM node id that is the via node of the turn NodeID turn_via_node; // name of the street that leads to the turn diff --git a/include/engine/routing_algorithms/routing_base.hpp b/include/engine/routing_algorithms/routing_base.hpp index c4a5007fc61..4bd564d2164 100644 --- a/include/engine/routing_algorithms/routing_base.hpp +++ b/include/engine/routing_algorithms/routing_base.hpp @@ -144,7 +144,7 @@ void annotatePath(const FacadeT &facade, // datastructures to hold extracted data from geometry std::vector id_vector; - std::vector osm_way_id_vector; + std::vector osm_way_id_vector; std::vector weight_vector; std::vector duration_vector; std::vector datasource_vector; diff --git a/include/extractor/node_based_edge.hpp b/include/extractor/node_based_edge.hpp index 09148422a15..6da911f7129 100644 --- a/include/extractor/node_based_edge.hpp +++ b/include/extractor/node_based_edge.hpp @@ -20,7 +20,7 @@ namespace extractor // while CompressedEdgeContainer::ZipEdges and store it in the segment data // to use when building found path annotations using OSMWayIDMapKey = std::pair; -using OSMWayIDMap = std::map; +using OSMWayIDMap = std::map; // Flags describing the class of the road. This data is used during creation of graphs/guidance // generation but is not available in annotation/navigation diff --git a/include/extractor/segment_data_container.hpp b/include/extractor/segment_data_container.hpp index 76d3b5c0a48..cbb6e8b621f 100644 --- a/include/extractor/segment_data_container.hpp +++ b/include/extractor/segment_data_container.hpp @@ -10,10 +10,12 @@ #include #include +#include #include #include +#include #include #include @@ -56,7 +58,7 @@ template class SegmentDataContainerImpl using DirectionalGeometryID = std::uint32_t; using SegmentOffset = std::uint32_t; using SegmentNodeVector = Vector; - using SegmentOSMWayVector = Vector; + using SegmentOSMWayVector = Vector; using SegmentWeightVector = PackedVector; using SegmentDurationVector = PackedVector; using SegmentDatasourceVector = Vector; @@ -102,7 +104,9 @@ template class SegmentDataContainerImpl auto GetReverseOSMWayIDs(const DirectionalGeometryID id) { - return boost::adaptors::reverse(GetForwardOSMWayIDs(id)); + // return boost::adaptors::reverse(GetForwardOSMWayIDs(id)); + return boost::adaptors::reverse( + boost::adaptors::transform(GetForwardOSMWayIDs(id), std::negate())); } auto GetForwardDurations(const DirectionalGeometryID id) @@ -176,7 +180,9 @@ template class SegmentDataContainerImpl auto GetReverseOSMWayIDs(const DirectionalGeometryID id) const { - return boost::adaptors::reverse(GetForwardOSMWayIDs(id)); + // return boost::adaptors::reverse(GetForwardOSMWayIDs(id)); + return boost::adaptors::reverse( + boost::adaptors::transform(GetForwardOSMWayIDs(id), std::negate())); } auto GetForwardDurations(const DirectionalGeometryID id) const diff --git a/include/storage/view_factory.hpp b/include/storage/view_factory.hpp index 6780a68a283..ef188b08e08 100644 --- a/include/storage/view_factory.hpp +++ b/include/storage/view_factory.hpp @@ -134,7 +134,7 @@ inline auto make_segment_data_view(const SharedDataIndex &index, const std::stri auto num_entries = index.GetBlockEntries(name + "/nodes"); - auto osm_way_list = make_vector_view(index, name + "/osm_ways"); + auto osm_way_list = make_vector_view(index, name + "/osm_ways"); extractor::SegmentDataView::SegmentWeightVector fwd_weight_list( make_vector_view( diff --git a/include/util/typedefs.hpp b/include/util/typedefs.hpp index b3e5a8d461b..4b9478e0c36 100644 --- a/include/util/typedefs.hpp +++ b/include/util/typedefs.hpp @@ -53,6 +53,7 @@ using OSMNodeID = osrm::Alias; static_assert(std::is_pod(), "OSMNodeID is not a valid alias"); using OSMWayID = osrm::Alias; static_assert(std::is_pod(), "OSMWayID is not a valid alias"); +using OSMWayIDDir = std::int64_t; using DuplicatedNodeID = std::uint64_t; using RestrictionID = std::uint64_t; diff --git a/src/extractor/compressed_edge_container.cpp b/src/extractor/compressed_edge_container.cpp index 92db95896fc..6c5f9e13b93 100644 --- a/src/extractor/compressed_edge_container.cpp +++ b/src/extractor/compressed_edge_container.cpp @@ -282,7 +282,7 @@ unsigned CompressedEdgeContainer::ZipEdges(const EdgeID f_edge_id, const auto &first_node = reverse_bucket.back(); auto prev_node_id = first_node.node_id; - auto osm_way_id = SPECIAL_OSM_WAYID; + OSMWayIDDir osm_way_id = 0; constexpr DatasourceID LUA_SOURCE = 0; segment_data->nodes.emplace_back(first_node.node_id); @@ -304,21 +304,19 @@ unsigned CompressedEdgeContainer::ZipEdges(const EdgeID f_edge_id, if (node_id != prev_node_id) { auto find_way_id = osm_way_id_map.find(OSMWayIDMapKey(prev_node_id, node_id)); - if (find_way_id == osm_way_id_map.cend()) + if (find_way_id != osm_way_id_map.cend()) { - find_way_id = osm_way_id_map.find(OSMWayIDMapKey(node_id, prev_node_id)); + segment_data->osm_ways.emplace_back(osm_way_id = find_way_id->second); + util::Log(logDEBUG) << "zipped_geometry_id: " << zipped_geometry_id << " " + << prev_node_id << "->" << node_id << " = " << osm_way_id; } - if (find_way_id == osm_way_id_map.cend()) + else { util::Log(logERROR) << "OSM Way ID not found for (nbg) nodes, it should never be happened: " << prev_node_id << "<-x->" << node_id; segment_data->osm_ways.emplace_back(osm_way_id); } - else - { - segment_data->osm_ways.emplace_back(osm_way_id = find_way_id->second); - } } else { @@ -341,21 +339,19 @@ unsigned CompressedEdgeContainer::ZipEdges(const EdgeID f_edge_id, if (node_id != prev_node_id) { auto find_way_id = osm_way_id_map.find(OSMWayIDMapKey(prev_node_id, node_id)); - if (find_way_id == osm_way_id_map.cend()) + if (find_way_id != osm_way_id_map.cend()) { - find_way_id = osm_way_id_map.find(OSMWayIDMapKey(node_id, prev_node_id)); + segment_data->osm_ways.emplace_back(osm_way_id = find_way_id->second); + util::Log(logDEBUG) << "zipped_geometry_id: " << zipped_geometry_id << " " + << prev_node_id << "->" << node_id << " = " << osm_way_id; } - if (find_way_id == osm_way_id_map.cend()) + else { util::Log(logERROR) << "OSM Way ID not found for (nbg) nodes, it should never be happened: " << prev_node_id << "<-x->" << node_id; segment_data->osm_ways.emplace_back(osm_way_id); } - else - { - segment_data->osm_ways.emplace_back(osm_way_id = find_way_id->second); - } } else { diff --git a/src/extractor/extractor.cpp b/src/extractor/extractor.cpp index eb9b6829f26..e5942e41e7a 100644 --- a/src/extractor/extractor.cpp +++ b/src/extractor/extractor.cpp @@ -635,8 +635,32 @@ Extractor::ParseOSMData(ScriptingEnvironment &scripting_environment, // Fill OSM Way ID Lookup Map to use it later for (auto edge : extraction_containers.all_edges_list) { - osm_way_id_map[OSMWayIDMapKey(edge.result.source, edge.result.target)] = - edge.result.osm_way_id; + OSMWayIDDir way_id = edge.result.osm_way_id.__value; + OSMNodeID osm_source_id = edge.result.osm_source_id; + OSMNodeID osm_target_id = edge.result.osm_target_id; + if ((edge.result.source < edge.result.target && osm_source_id > osm_target_id) || + (edge.result.source > edge.result.target && osm_source_id < osm_target_id)) + { + // Bogus criteria? + way_id = -way_id; + std::swap(osm_source_id, osm_target_id); + } + if (edge.result.flags.forward) + { + osm_way_id_map[OSMWayIDMapKey(edge.result.source, edge.result.target)] = way_id; + util::Log(logDEBUG) + << "osm_way_id_map: " << edge.result.source << "->" << edge.result.target << " = " + << osm_way_id_map[OSMWayIDMapKey(edge.result.source, edge.result.target)] << " (" + << osm_source_id << "->" << osm_target_id << ")"; + } + if (edge.result.flags.backward) + { + osm_way_id_map[OSMWayIDMapKey(edge.result.target, edge.result.source)] = -way_id; + util::Log(logDEBUG) + << "osm_way_id_map: " << edge.result.target << "->" << edge.result.source << " = " + << osm_way_id_map[OSMWayIDMapKey(edge.result.target, edge.result.source)] << " (" + << osm_target_id << "->" << osm_source_id << ")"; + } } TIMER_STOP(extracting); diff --git a/unit_tests/library/route.cpp b/unit_tests/library/route.cpp index 75444061a76..dd9e0c1ce9e 100644 --- a/unit_tests/library/route.cpp +++ b/unit_tests/library/route.cpp @@ -602,7 +602,7 @@ BOOST_AUTO_TEST_CASE(test_manual_setting_of_annotations_property_new_api) } using NodePair = std::pair; -using NodePairToWayIDMap = std::map; +using NodePairToWayIDMap = std::map; NodePairToWayIDMap read_node_pair_to_way_id_map(osmium::io::Reader &osm) { @@ -611,11 +611,11 @@ NodePairToWayIDMap read_node_pair_to_way_id_map(osmium::io::Reader &osm) NodePairToWayIDMap ret; void way(const osmium::Way &way) { - auto first = osmium::unsigned_object_id_type(-1); + osmium::unsigned_object_id_type first = 0; for (const auto &n : way.nodes()) { const auto second = n.positive_ref(); - if (first != osmium::unsigned_object_id_type(-1)) + if (first != 0) { ret[{first, second}] = way.id(); } @@ -700,15 +700,20 @@ LonLatVector check_route_annotated_ways(std::vector &coo for (nodes_it++; nodes_it != nodes.cend(); nodes_it++, ways_it++) { osmium::unsigned_object_id_type second = nodes_it->get().value; - osmium::unsigned_object_id_type way_id = ways_it->get().value; + int64_t way_id = ways_it->get().value; auto found = node_pair_to_way_id_map.find(NodePair(first, second)); + auto reverse = false; if (found == node_pair_to_way_id_map.end()) + { + reverse = true; found = node_pair_to_way_id_map.find(NodePair(second, first)); + } BOOST_CHECK_MESSAGE(found != node_pair_to_way_id_map.end(), "The node pair not found: " << first << "<->" << second); - BOOST_CHECK_MESSAGE(found->second == way_id, + int64_t found_way_id = reverse ? -found->second : found->second; + BOOST_CHECK_MESSAGE(found_way_id == way_id, "The node pair way doesn't correspond: " << first << "<->" << second - << "=" << found->second + << "=" << found_way_id << "=?=" << way_id); first = second; } diff --git a/unit_tests/mocks/mock_datafacade.hpp b/unit_tests/mocks/mock_datafacade.hpp index 2270bfffd7c..dad8162f781 100644 --- a/unit_tests/mocks/mock_datafacade.hpp +++ b/unit_tests/mocks/mock_datafacade.hpp @@ -66,7 +66,7 @@ class MockBaseDataFacade : public engine::datafacade::BaseDataFacade } OSMWayForwardRange GetUncompressedForwardWayIDs(const EdgeID /* id */) const override { - static OSMWayID data[] = {0, 1, 2, 3}; + static OSMWayIDDir data[] = {0, 1, 2, 3}; static extractor::SegmentDataView::SegmentOSMWayVector ways(data, 4); return boost::make_iterator_range(ways.cbegin(), ways.cend()); } From 4abfeaa09fbd94e90e6a8bbe752328577efa7812 Mon Sep 17 00:00:00 2001 From: Vsevolod Novikov Date: Mon, 22 Feb 2021 22:31:58 +0300 Subject: [PATCH 06/10] #5325 changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a11ed9b6e4..0452221d6f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,9 @@ # Unreleased + - Changes from 5.24.0 + - Features: + - ADDED: a new `ways` subsection in the `annotations` section containing way IDs along the found path, with sign meaning direction [#5325] + - API: + - Fixed item type for `nodes` section of the `annotations` flatbuffers output format # 5.24.0 - Changes from 5.23.0 From eb2eeb9bace7b79c5a80f285c3adcb651b2e4314 Mon Sep 17 00:00:00 2001 From: Vsevolod Novikov Date: Tue, 23 Feb 2021 14:46:15 +0300 Subject: [PATCH 07/10] #5325 Fixed CI problems --- CHANGELOG.md | 4 ++-- include/extractor/extractor_callbacks.hpp | 2 -- src/extractor/extractor.cpp | 1 - src/extractor/extractor_callbacks.cpp | 3 +-- unit_tests/engine/offline_facade.cpp | 5 +++-- unit_tests/mocks/mock_datafacade.hpp | 3 ++- 6 files changed, 8 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0452221d6f3..dc2f1c160c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,9 @@ # Unreleased - Changes from 5.24.0 - Features: - - ADDED: a new `ways` subsection in the `annotations` section containing way IDs along the found path, with sign meaning direction [#5325] + - ADDED: a new `ways` subsection in the `annotations` section containing way IDs along the found path, with sign meaning direction [#5325](https://github.com/Project-OSRM/osrm-backend/issues/5325) - API: - - Fixed item type for `nodes` section of the `annotations` flatbuffers output format + - FIXED: item type for `nodes` section of the `annotations` flatbuffers output format # 5.24.0 - Changes from 5.23.0 diff --git a/include/extractor/extractor_callbacks.hpp b/include/extractor/extractor_callbacks.hpp index 197f663ad98..4b0534c1fb7 100644 --- a/include/extractor/extractor_callbacks.hpp +++ b/include/extractor/extractor_callbacks.hpp @@ -70,7 +70,6 @@ class ExtractorCallbacks ExtractionContainers &external_memory; std::unordered_map &classes_map; LaneDescriptionMap &lane_description_map; - OSMWayIDMap &osm_way_id_map; bool fallback_to_duration; bool force_split_edges; @@ -80,7 +79,6 @@ class ExtractorCallbacks explicit ExtractorCallbacks(ExtractionContainers &extraction_containers, std::unordered_map &classes_map, LaneDescriptionMap &lane_description_map, - OSMWayIDMap &osm_way_id_map, const ProfileProperties &properties); ExtractorCallbacks(const ExtractorCallbacks &) = delete; diff --git a/src/extractor/extractor.cpp b/src/extractor/extractor.cpp index e5942e41e7a..037411ae52b 100644 --- a/src/extractor/extractor.cpp +++ b/src/extractor/extractor.cpp @@ -429,7 +429,6 @@ Extractor::ParseOSMData(ScriptingEnvironment &scripting_environment, std::make_unique(extraction_containers, classes_map, turn_lane_map, - osm_way_id_map, scripting_environment.GetProfileProperties()); // get list of supported relation types diff --git a/src/extractor/extractor_callbacks.cpp b/src/extractor/extractor_callbacks.cpp index bc5f5627ad4..35e2f6ec1eb 100644 --- a/src/extractor/extractor_callbacks.cpp +++ b/src/extractor/extractor_callbacks.cpp @@ -29,10 +29,9 @@ namespace extractor ExtractorCallbacks::ExtractorCallbacks(ExtractionContainers &extraction_containers_, std::unordered_map &classes_map, LaneDescriptionMap &lane_description_map, - OSMWayIDMap &osm_way_id_map, const ProfileProperties &properties) : external_memory(extraction_containers_), classes_map(classes_map), - lane_description_map(lane_description_map), osm_way_id_map(osm_way_id_map), + lane_description_map(lane_description_map), fallback_to_duration(properties.fallback_to_duration), force_split_edges(properties.force_split_edges) { diff --git a/unit_tests/engine/offline_facade.cpp b/unit_tests/engine/offline_facade.cpp index e6c9d70b045..b5cab414eaa 100644 --- a/unit_tests/engine/offline_facade.cpp +++ b/unit_tests/engine/offline_facade.cpp @@ -171,9 +171,10 @@ class ContiguousInternalMemoryDataFacade return {}; } - OSMWayReverseRange GetUncompressedReverseWayIDs(const EdgeID /*id*/) const override + OSMWayReverseRange GetUncompressedReverseWayIDs(const EdgeID id) const override { - return OSMWayReverseRange(OSMWayForwardRange()); + return boost::adaptors::reverse( + boost::adaptors::transform(GetUncompressedForwardWayIDs(id), std::negate())); } TurnPenalty GetWeightPenaltyForEdgeID(const unsigned /*id*/) const override diff --git a/unit_tests/mocks/mock_datafacade.hpp b/unit_tests/mocks/mock_datafacade.hpp index dad8162f781..e5dc49b1dfc 100644 --- a/unit_tests/mocks/mock_datafacade.hpp +++ b/unit_tests/mocks/mock_datafacade.hpp @@ -72,7 +72,8 @@ class MockBaseDataFacade : public engine::datafacade::BaseDataFacade } OSMWayReverseRange GetUncompressedReverseWayIDs(const EdgeID id) const override { - return OSMWayReverseRange(GetUncompressedForwardWayIDs(id)); + return boost::adaptors::reverse( + boost::adaptors::transform(GetUncompressedForwardWayIDs(id), std::negate())); } WeightForwardRange GetUncompressedForwardWeights(const EdgeID /* id */) const override { From b1cfc024544813953c94958f487f15c289642fc1 Mon Sep 17 00:00:00 2001 From: Vsevolod Novikov Date: Tue, 23 Feb 2021 16:08:01 +0300 Subject: [PATCH 08/10] #5325 Fixed CI and review --- CHANGELOG.md | 2 +- include/engine/guidance/assemble_geometry.hpp | 2 -- unit_tests/engine/offline_facade.cpp | 4 ++-- unit_tests/mocks/mock_datafacade.hpp | 4 ++-- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc2f1c160c3..18f68829e38 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ - Features: - ADDED: a new `ways` subsection in the `annotations` section containing way IDs along the found path, with sign meaning direction [#5325](https://github.com/Project-OSRM/osrm-backend/issues/5325) - API: - - FIXED: item type for `nodes` section of the `annotations` flatbuffers output format + - FIXED: item type for `nodes` section of the `annotations` flatbuffers output format [#5970](https://github.com/Project-OSRM/osrm-backend/issues/5970) # 5.24.0 - Changes from 5.23.0 diff --git a/include/engine/guidance/assemble_geometry.hpp b/include/engine/guidance/assemble_geometry.hpp index b4e5028fb58..1c0be9502d1 100644 --- a/include/engine/guidance/assemble_geometry.hpp +++ b/include/engine/guidance/assemble_geometry.hpp @@ -56,11 +56,9 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade, reversed_source ? source_node.reverse_segment_id.id : source_node.forward_segment_id.id; const auto source_geometry_id = facade.GetGeometryIndex(source_node_id).id; const auto source_geometry = facade.GetUncompressedForwardGeometry(source_geometry_id); - // const auto source_osm_way_ids = facade.GetUncompressedForwardWayIDs(source_geometry_id); geometry.osm_node_ids.push_back( facade.GetOSMNodeIDOfNode(source_geometry(source_segment_start_coordinate))); - // geometry.osm_way_ids.push_back(source_osm_way_ids(source_segment_start_coordinate))); auto cumulative_distance = 0.; auto current_distance = 0.; diff --git a/unit_tests/engine/offline_facade.cpp b/unit_tests/engine/offline_facade.cpp index b5cab414eaa..0fe6c8a4412 100644 --- a/unit_tests/engine/offline_facade.cpp +++ b/unit_tests/engine/offline_facade.cpp @@ -173,8 +173,8 @@ class ContiguousInternalMemoryDataFacade OSMWayReverseRange GetUncompressedReverseWayIDs(const EdgeID id) const override { - return boost::adaptors::reverse( - boost::adaptors::transform(GetUncompressedForwardWayIDs(id), std::negate())); + return boost::adaptors::reverse(boost::adaptors::transform(GetUncompressedForwardWayIDs(id), + std::negate())); } TurnPenalty GetWeightPenaltyForEdgeID(const unsigned /*id*/) const override diff --git a/unit_tests/mocks/mock_datafacade.hpp b/unit_tests/mocks/mock_datafacade.hpp index e5dc49b1dfc..3831b3a32a6 100644 --- a/unit_tests/mocks/mock_datafacade.hpp +++ b/unit_tests/mocks/mock_datafacade.hpp @@ -72,8 +72,8 @@ class MockBaseDataFacade : public engine::datafacade::BaseDataFacade } OSMWayReverseRange GetUncompressedReverseWayIDs(const EdgeID id) const override { - return boost::adaptors::reverse( - boost::adaptors::transform(GetUncompressedForwardWayIDs(id), std::negate())); + return boost::adaptors::reverse(boost::adaptors::transform(GetUncompressedForwardWayIDs(id), + std::negate())); } WeightForwardRange GetUncompressedForwardWeights(const EdgeID /* id */) const override { From 848e96238ec9c020ae85b509dd4b4cd4691b9a6f Mon Sep 17 00:00:00 2001 From: Vsevolod Novikov Date: Thu, 25 Feb 2021 11:45:59 +0300 Subject: [PATCH 09/10] #5325 Fixes after the revew --- .../extractor/compressed_edge_container.hpp | 5 +- .../extractor/node_based_graph_factory.hpp | 2 +- include/extractor/segment_data_container.hpp | 2 - src/extractor/compressed_edge_container.cpp | 46 ++++++------------- src/extractor/node_based_graph_factory.cpp | 2 +- unit_tests/library/route.cpp | 1 - 6 files changed, 20 insertions(+), 38 deletions(-) diff --git a/include/extractor/compressed_edge_container.hpp b/include/extractor/compressed_edge_container.hpp index 7412d7606f9..597658f754e 100644 --- a/include/extractor/compressed_edge_container.hpp +++ b/include/extractor/compressed_edge_container.hpp @@ -49,8 +49,9 @@ class CompressedEdgeContainer const SegmentWeight duration); void InitializeBothwayVector(); - unsigned - ZipEdges(const unsigned f_edge_pos, const unsigned r_edge_pos, OSMWayIDMap &osm_way_id_map); + unsigned ZipEdges(const unsigned f_edge_pos, + const unsigned r_edge_pos, + const OSMWayIDMap &osm_way_id_map); bool HasEntryForID(const EdgeID edge_id) const; bool HasZippedEntryForForwardID(const EdgeID edge_id) const; diff --git a/include/extractor/node_based_graph_factory.hpp b/include/extractor/node_based_graph_factory.hpp index 7b44e7bd60a..02c781052ac 100644 --- a/include/extractor/node_based_graph_factory.hpp +++ b/include/extractor/node_based_graph_factory.hpp @@ -74,7 +74,7 @@ class NodeBasedGraphFactory // Most ways are bidirectional, making the geometry in forward and backward direction the same, // except for reversal. We make use of this fact by keeping only one representation of the // geometry around - void CompressGeometry(OSMWayIDMap &osm_way_id_map); + void CompressGeometry(const OSMWayIDMap &osm_way_id_map); // After graph compression, some of the annotation entries might not be referenced anymore. We // compress the annotation data by relabeling the node-based graph references and removing all diff --git a/include/extractor/segment_data_container.hpp b/include/extractor/segment_data_container.hpp index cbb6e8b621f..96ff4a22428 100644 --- a/include/extractor/segment_data_container.hpp +++ b/include/extractor/segment_data_container.hpp @@ -104,7 +104,6 @@ template class SegmentDataContainerImpl auto GetReverseOSMWayIDs(const DirectionalGeometryID id) { - // return boost::adaptors::reverse(GetForwardOSMWayIDs(id)); return boost::adaptors::reverse( boost::adaptors::transform(GetForwardOSMWayIDs(id), std::negate())); } @@ -180,7 +179,6 @@ template class SegmentDataContainerImpl auto GetReverseOSMWayIDs(const DirectionalGeometryID id) const { - // return boost::adaptors::reverse(GetForwardOSMWayIDs(id)); return boost::adaptors::reverse( boost::adaptors::transform(GetForwardOSMWayIDs(id), std::negate())); } diff --git a/src/extractor/compressed_edge_container.cpp b/src/extractor/compressed_edge_container.cpp index 6c5f9e13b93..e3796448944 100644 --- a/src/extractor/compressed_edge_container.cpp +++ b/src/extractor/compressed_edge_container.cpp @@ -264,7 +264,7 @@ void CompressedEdgeContainer::InitializeBothwayVector() unsigned CompressedEdgeContainer::ZipEdges(const EdgeID f_edge_id, const EdgeID r_edge_id, - OSMWayIDMap &osm_way_id_map) + const OSMWayIDMap &osm_way_id_map) { if (!segment_data) InitializeBothwayVector(); @@ -293,14 +293,7 @@ unsigned CompressedEdgeContainer::ZipEdges(const EdgeID f_edge_id, segment_data->fwd_datasources.emplace_back(LUA_SOURCE); segment_data->rev_datasources.emplace_back(LUA_SOURCE); - for (std::size_t i = 0; i < forward_bucket.size() - 1; ++i) - { - const auto &fwd_node = forward_bucket.at(i); - const auto &rev_node = reverse_bucket.at(reverse_bucket.size() - 2 - i); - - BOOST_ASSERT(fwd_node.node_id == rev_node.node_id); - - auto node_id = fwd_node.node_id; + auto store_way_id = [&](const NodeID prev_node_id, const NodeID node_id) { if (node_id != prev_node_id) { auto find_way_id = osm_way_id_map.find(OSMWayIDMapKey(prev_node_id, node_id)); @@ -323,6 +316,18 @@ unsigned CompressedEdgeContainer::ZipEdges(const EdgeID f_edge_id, // Special case (artificial lighting signal edge) segment_data->osm_ways.emplace_back(osm_way_id); } + }; + + for (std::size_t i = 0; i < forward_bucket.size() - 1; ++i) + { + const auto &fwd_node = forward_bucket.at(i); + const auto &rev_node = reverse_bucket.at(reverse_bucket.size() - 2 - i); + + BOOST_ASSERT(fwd_node.node_id == rev_node.node_id); + + auto node_id = fwd_node.node_id; + + store_way_id(prev_node_id, node_id); segment_data->nodes.emplace_back(fwd_node.node_id); segment_data->fwd_weights.emplace_back(fwd_node.weight); @@ -336,28 +341,7 @@ unsigned CompressedEdgeContainer::ZipEdges(const EdgeID f_edge_id, const auto &last_node = forward_bucket.back(); auto node_id = last_node.node_id; - if (node_id != prev_node_id) - { - auto find_way_id = osm_way_id_map.find(OSMWayIDMapKey(prev_node_id, node_id)); - if (find_way_id != osm_way_id_map.cend()) - { - segment_data->osm_ways.emplace_back(osm_way_id = find_way_id->second); - util::Log(logDEBUG) << "zipped_geometry_id: " << zipped_geometry_id << " " - << prev_node_id << "->" << node_id << " = " << osm_way_id; - } - else - { - util::Log(logERROR) - << "OSM Way ID not found for (nbg) nodes, it should never be happened: " - << prev_node_id << "<-x->" << node_id; - segment_data->osm_ways.emplace_back(osm_way_id); - } - } - else - { - // Special case (artificial lighting signal edge) - segment_data->osm_ways.emplace_back(osm_way_id); - } + store_way_id(prev_node_id, node_id); // Make osm_ways vector size the same as // nodes vector size to use index vector for the both diff --git a/src/extractor/node_based_graph_factory.cpp b/src/extractor/node_based_graph_factory.cpp index 4ca097b467a..61ee5e5274d 100644 --- a/src/extractor/node_based_graph_factory.cpp +++ b/src/extractor/node_based_graph_factory.cpp @@ -94,7 +94,7 @@ void NodeBasedGraphFactory::Compress(ScriptingEnvironment &scripting_environment compressed_edge_container); } -void NodeBasedGraphFactory::CompressGeometry(OSMWayIDMap &osm_way_id_map) +void NodeBasedGraphFactory::CompressGeometry(const OSMWayIDMap &osm_way_id_map) { for (const auto nbg_node_u : util::irange(0u, compressed_output_graph.GetNumberOfNodes())) { diff --git a/unit_tests/library/route.cpp b/unit_tests/library/route.cpp index dd9e0c1ce9e..8f112d7903d 100644 --- a/unit_tests/library/route.cpp +++ b/unit_tests/library/route.cpp @@ -733,7 +733,6 @@ BOOST_AUTO_TEST_CASE(test_route_annotated_ways) BOOST_TEST_MESSAGE("split_trace_locations with steps"); check_route_annotated_ways(coordinates, osrm, node_pair_to_way_id_map, true); coordinates = get_locations_in_big_component(); - // auto coords = BOOST_TEST_MESSAGE("locations_in_big_component without steps"); check_route_annotated_ways(coordinates, osrm, node_pair_to_way_id_map, false); BOOST_TEST_MESSAGE("locations_in_big_component with steps"); From 129d9549d3debc95564eaeff1a808236cbe4cebf Mon Sep 17 00:00:00 2001 From: Vsevolod Novikov Date: Wed, 17 Mar 2021 12:03:50 +0300 Subject: [PATCH 10/10] #5325 Make osm_ids optional after the revew --- CMakeLists.txt | 2 +- include/engine/api/route_api.hpp | 6 +++-- .../contiguous_internalmem_datafacade.hpp | 4 +++ include/engine/datafacade/datafacade_base.hpp | 1 + include/engine/guidance/assemble_geometry.hpp | 25 +++++++++++-------- .../routing_algorithms/routing_base.hpp | 6 ++--- include/extractor/extractor_config.hpp | 4 ++- include/extractor/files.hpp | 6 +++-- include/extractor/segment_data_container.hpp | 5 ++++ include/extractor/serialization.hpp | 9 ++++++- src/extractor/extractor.cpp | 1 + src/tools/extract.cpp | 7 +++++- src/updater/updater.cpp | 3 ++- unit_tests/engine/offline_facade.cpp | 1 + unit_tests/mocks/mock_datafacade.hpp | 1 + 15 files changed, 58 insertions(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e6feb6de9aa..857b77b4ede 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -242,7 +242,7 @@ endif() if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -ggdb") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Og -ggdb") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -ggdb") endif() diff --git a/include/engine/api/route_api.hpp b/include/engine/api/route_api.hpp index dadc1244249..aa4a7610e11 100644 --- a/include/engine/api/route_api.hpp +++ b/include/engine/api/route_api.hpp @@ -504,7 +504,8 @@ class RouteAPI : public BaseAPI } } std::vector ways; - if (requested_annotations & RouteParameters::AnnotationsType::Ways) + if (requested_annotations & RouteParameters::AnnotationsType::Ways && + leg_geometry.osm_way_ids.size()) { ways.reserve(leg_geometry.osm_way_ids.size()); for (const auto way_id : leg_geometry.osm_way_ids) @@ -843,7 +844,8 @@ class RouteAPI : public BaseAPI } annotation.values["nodes"] = std::move(nodes); } - if (requested_annotations & RouteParameters::AnnotationsType::Ways) + if (requested_annotations & RouteParameters::AnnotationsType::Ways && + leg_geometry.osm_way_ids.size()) { util::json::Array ways; ways.values.reserve(leg_geometry.osm_way_ids.size()); diff --git a/include/engine/datafacade/contiguous_internalmem_datafacade.hpp b/include/engine/datafacade/contiguous_internalmem_datafacade.hpp index 70b6d2d98d0..ee0e7bf4e4b 100644 --- a/include/engine/datafacade/contiguous_internalmem_datafacade.hpp +++ b/include/engine/datafacade/contiguous_internalmem_datafacade.hpp @@ -259,6 +259,10 @@ class ContiguousInternalMemoryDataFacadeBase : public BaseDataFacade { return segment_data.GetReverseOSMWayIDs(id); } + bool GetUncompressedWayIDsSkipped() const override final + { + return segment_data.GetOSMWaysSkipped(); + } DurationForwardRange GetUncompressedForwardDurations(const EdgeID id) const override final { diff --git a/include/engine/datafacade/datafacade_base.hpp b/include/engine/datafacade/datafacade_base.hpp index 3b5a998f3a0..a5199c90154 100644 --- a/include/engine/datafacade/datafacade_base.hpp +++ b/include/engine/datafacade/datafacade_base.hpp @@ -93,6 +93,7 @@ class BaseDataFacade virtual OSMWayForwardRange GetUncompressedForwardWayIDs(const EdgeID id) const = 0; virtual OSMWayReverseRange GetUncompressedReverseWayIDs(const EdgeID id) const = 0; + virtual bool GetUncompressedWayIDsSkipped() const = 0; virtual NodeForwardRange GetUncompressedForwardGeometry(const EdgeID id) const = 0; virtual NodeReverseRange GetUncompressedReverseGeometry(const EdgeID id) const = 0; diff --git a/include/engine/guidance/assemble_geometry.hpp b/include/engine/guidance/assemble_geometry.hpp index 1c0be9502d1..1bc09c5135e 100644 --- a/include/engine/guidance/assemble_geometry.hpp +++ b/include/engine/guidance/assemble_geometry.hpp @@ -100,7 +100,8 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade, path_point.datasource_id}); geometry.locations.push_back(std::move(coordinate)); geometry.osm_node_ids.push_back(osm_node_id); - geometry.osm_way_ids.push_back(path_point.osm_way_id); + if (!facade.GetUncompressedWayIDsSkipped()) + geometry.osm_way_ids.push_back(path_point.osm_way_id); } } current_distance = @@ -161,18 +162,20 @@ inline LegGeometry assembleGeometry(const datafacade::BaseDataFacade &facade, const auto target_geometry = facade.GetUncompressedForwardGeometry(target_geometry_id); geometry.osm_node_ids.push_back( facade.GetOSMNodeIDOfNode(target_geometry(target_segment_end_coordinate))); - if (reversed_target) + if (!facade.GetUncompressedWayIDsSkipped()) { - const auto target_osm_way_ids = facade.GetUncompressedReverseWayIDs(target_geometry_id); - geometry.osm_way_ids.push_back( - target_osm_way_ids(target_osm_way_ids.size() - target_node.fwd_segment_position - 1)); - } - else - { - const auto target_osm_way_ids = facade.GetUncompressedForwardWayIDs(target_geometry_id); - geometry.osm_way_ids.push_back(target_osm_way_ids(target_node.fwd_segment_position)); + if (reversed_target) + { + const auto target_osm_way_ids = facade.GetUncompressedReverseWayIDs(target_geometry_id); + geometry.osm_way_ids.push_back(target_osm_way_ids( + target_osm_way_ids.size() - target_node.fwd_segment_position - 1)); + } + else + { + const auto target_osm_way_ids = facade.GetUncompressedForwardWayIDs(target_geometry_id); + geometry.osm_way_ids.push_back(target_osm_way_ids(target_node.fwd_segment_position)); + } } - BOOST_ASSERT(geometry.segment_distances.size() == geometry.segment_offsets.size() - 1); BOOST_ASSERT(geometry.locations.size() > geometry.segment_distances.size()); BOOST_ASSERT(geometry.annotations.size() == geometry.locations.size() - 1); diff --git a/include/engine/routing_algorithms/routing_base.hpp b/include/engine/routing_algorithms/routing_base.hpp index 4bd564d2164..e9f57398293 100644 --- a/include/engine/routing_algorithms/routing_base.hpp +++ b/include/engine/routing_algorithms/routing_base.hpp @@ -194,7 +194,7 @@ void annotatePath(const FacadeT &facade, BOOST_ASSERT(datasource_vector.size() > 0); BOOST_ASSERT(weight_vector.size() + 1 == id_vector.size()); BOOST_ASSERT(duration_vector.size() + 1 == id_vector.size()); - BOOST_ASSERT(osm_way_id_vector.size() + 1 == id_vector.size()); + BOOST_ASSERT(!osm_way_id_vector.size() || osm_way_id_vector.size() + 1 == id_vector.size()); const bool is_first_segment = unpacked_path.empty(); @@ -219,7 +219,7 @@ void annotatePath(const FacadeT &facade, { unpacked_path.push_back( PathData{*node_from, - osm_way_id_vector[segment_idx], + osm_way_id_vector.size() ? osm_way_id_vector[segment_idx] : 0, id_vector[segment_idx + 1], name_index, is_segregated, @@ -295,7 +295,7 @@ void annotatePath(const FacadeT &facade, BOOST_ASSERT(facade.GetTravelMode(target_node_id) > 0); unpacked_path.push_back( PathData{target_node_id, - osm_way_id_vector[segment_idx], + osm_way_id_vector.size() ? osm_way_id_vector[segment_idx] : 0, id_vector[start_index < end_index ? segment_idx + 1 : segment_idx - 1], facade.GetNameIndex(target_node_id), facade.IsSegregated(target_node_id), diff --git a/include/extractor/extractor_config.hpp b/include/extractor/extractor_config.hpp index b3822d587ce..da90abdd310 100644 --- a/include/extractor/extractor_config.hpp +++ b/include/extractor/extractor_config.hpp @@ -70,7 +70,8 @@ struct ExtractorConfig final : storage::IOConfig ".osrm.cnbg", ".osrm.cnbg_to_ebg", ".osrm.maneuver_overrides"}), - requested_num_threads(0), parse_conditionals(false), use_locations_cache(true) + requested_num_threads(0), parse_conditionals(false), use_locations_cache(true), + skip_osm_ways(false) { } @@ -92,6 +93,7 @@ struct ExtractorConfig final : storage::IOConfig bool use_metadata; bool parse_conditionals; bool use_locations_cache; + bool skip_osm_ways; }; } // namespace extractor } // namespace osrm diff --git a/include/extractor/files.hpp b/include/extractor/files.hpp index 6c0445e9b45..b71d97edbaa 100644 --- a/include/extractor/files.hpp +++ b/include/extractor/files.hpp @@ -206,7 +206,9 @@ inline void readSegmentData(const boost::filesystem::path &path, SegmentDataT &s // writes .osrm.geometry template -inline void writeSegmentData(const boost::filesystem::path &path, const SegmentDataT &segment_data) +inline void writeSegmentData(const boost::filesystem::path &path, + bool skip_osm_ways, + const SegmentDataT &segment_data) { static_assert(std::is_same::value || std::is_same::value, @@ -214,7 +216,7 @@ inline void writeSegmentData(const boost::filesystem::path &path, const SegmentD const auto fingerprint = storage::tar::FileWriter::GenerateFingerprint; storage::tar::FileWriter writer{path, fingerprint}; - serialization::write(writer, "/common/segment_data", segment_data); + serialization::write(writer, "/common/segment_data", skip_osm_ways, segment_data); } // reads .osrm.ebg_nodes diff --git a/include/extractor/segment_data_container.hpp b/include/extractor/segment_data_container.hpp index 96ff4a22428..e05e9f78e82 100644 --- a/include/extractor/segment_data_container.hpp +++ b/include/extractor/segment_data_container.hpp @@ -40,6 +40,7 @@ inline void read(storage::tar::FileReader &reader, template inline void write(storage::tar::FileWriter &writer, const std::string &name, + const bool skip_osm_ways, const detail::SegmentDataContainerImpl &segment_data); } // namespace serialization @@ -171,6 +172,8 @@ template class SegmentDataContainerImpl auto GetForwardOSMWayIDs(const DirectionalGeometryID id) const { + if (GetOSMWaysSkipped()) + return boost::make_iterator_range(osm_ways.cend(), osm_ways.cend()); const auto begin = osm_ways.cbegin() + index[id]; const auto end = osm_ways.cbegin() + index[id + 1] - 1; @@ -233,6 +236,7 @@ template class SegmentDataContainerImpl auto GetNumberOfGeometries() const { return index.size() - 1; } auto GetNumberOfSegments() const { return fwd_weights.size(); } + auto GetOSMWaysSkipped() const { return osm_ways.size() == 0; } friend void serialization::read(storage::tar::FileReader &reader, @@ -241,6 +245,7 @@ template class SegmentDataContainerImpl friend void serialization::write( storage::tar::FileWriter &writer, const std::string &name, + const bool skip_osm_ways, const detail::SegmentDataContainerImpl &segment_data); private: diff --git a/include/extractor/serialization.hpp b/include/extractor/serialization.hpp index 3ec5ae177e0..ddd3090a3d7 100644 --- a/include/extractor/serialization.hpp +++ b/include/extractor/serialization.hpp @@ -98,11 +98,18 @@ inline void read(storage::tar::FileReader &reader, template inline void write(storage::tar::FileWriter &writer, const std::string &name, + const bool skip_osm_ways, const detail::SegmentDataContainerImpl &segment_data) { storage::serialization::write(writer, name + "/index", segment_data.index); storage::serialization::write(writer, name + "/nodes", segment_data.nodes); - storage::serialization::write(writer, name + "/osm_ways", segment_data.osm_ways); + if (!skip_osm_ways) + storage::serialization::write(writer, name + "/osm_ways", segment_data.osm_ways); + else + storage::serialization::write( + writer, + name + "/osm_ways", + osrm::util::ViewOrVector()); util::serialization::write(writer, name + "/forward_weights", segment_data.fwd_weights); util::serialization::write(writer, name + "/reverse_weights", segment_data.rev_weights); util::serialization::write(writer, name + "/forward_durations", segment_data.fwd_durations); diff --git a/src/extractor/extractor.cpp b/src/extractor/extractor.cpp index 037411ae52b..715b796d278 100644 --- a/src/extractor/extractor.cpp +++ b/src/extractor/extractor.cpp @@ -321,6 +321,7 @@ int Extractor::run(ScriptingEnvironment &scripting_environment) // output the geometry of the node-based graph, needs to be done after the last usage, since it // destroys internal containers files::writeSegmentData(config.GetPath(".osrm.geometry"), + config.skip_osm_ways, *node_based_graph_factory.GetCompressedEdges().ToSegmentData()); util::Log() << "Saving edge-based node weights to file."; diff --git a/src/tools/extract.cpp b/src/tools/extract.cpp index 0cd1c7b4f75..7b3073711bb 100644 --- a/src/tools/extract.cpp +++ b/src/tools/extract.cpp @@ -74,7 +74,12 @@ return_code parseArguments(int argc, boost::program_options::bool_switch(&extractor_config.use_locations_cache) ->implicit_value(false) ->default_value(true), - "Use internal nodes locations cache for location-dependent data lookups"); + "Use internal nodes locations cache for location-dependent data lookups")( + "skip-osm-ways", + boost::program_options::bool_switch(&extractor_config.skip_osm_ways) + ->implicit_value(true) + ->default_value(false), + "Skip OSM Way IDs in annotations"); bool dummy; // hidden options, will be allowed on command line, but will not be diff --git a/src/updater/updater.cpp b/src/updater/updater.cpp index 13f10aa2995..c7491560dc3 100644 --- a/src/updater/updater.cpp +++ b/src/updater/updater.cpp @@ -623,7 +623,8 @@ Updater::LoadAndUpdateEdgeExpandedGraph(std::vector &e coordinates, osm_node_ids); // Now save out the updated compressed geometries - extractor::files::writeSegmentData(config.GetPath(".osrm.geometry"), segment_data); + extractor::files::writeSegmentData( + config.GetPath(".osrm.geometry"), segment_data.GetOSMWaysSkipped(), segment_data); TIMER_STOP(segment); util::Log() << "Updating segment data took " << TIMER_MSEC(segment) << "ms."; } diff --git a/unit_tests/engine/offline_facade.cpp b/unit_tests/engine/offline_facade.cpp index 0fe6c8a4412..394616640e7 100644 --- a/unit_tests/engine/offline_facade.cpp +++ b/unit_tests/engine/offline_facade.cpp @@ -170,6 +170,7 @@ class ContiguousInternalMemoryDataFacade { return {}; } + bool GetUncompressedWayIDsSkipped() const override { return true; } OSMWayReverseRange GetUncompressedReverseWayIDs(const EdgeID id) const override { diff --git a/unit_tests/mocks/mock_datafacade.hpp b/unit_tests/mocks/mock_datafacade.hpp index 3831b3a32a6..1af3876fcca 100644 --- a/unit_tests/mocks/mock_datafacade.hpp +++ b/unit_tests/mocks/mock_datafacade.hpp @@ -70,6 +70,7 @@ class MockBaseDataFacade : public engine::datafacade::BaseDataFacade static extractor::SegmentDataView::SegmentOSMWayVector ways(data, 4); return boost::make_iterator_range(ways.cbegin(), ways.cend()); } + bool GetUncompressedWayIDsSkipped() const override { return false; } OSMWayReverseRange GetUncompressedReverseWayIDs(const EdgeID id) const override { return boost::adaptors::reverse(boost::adaptors::transform(GetUncompressedForwardWayIDs(id),