Skip to content

Commit

Permalink
Project-OSRM#5325 Return way ID with sign meaning direction
Browse files Browse the repository at this point in the history
  • Loading branch information
nnseva committed Feb 22, 2021
1 parent 44bc0a5 commit d946025
Show file tree
Hide file tree
Showing 17 changed files with 91 additions and 48 deletions.
4 changes: 2 additions & 2 deletions docs/http.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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]
}
```
Expand Down
14 changes: 7 additions & 7 deletions include/engine/api/flatbuffers/fbresult_generated.h
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ struct AnnotationT : public flatbuffers::NativeTable {
std::vector<uint32_t> duration;
std::vector<uint32_t> datasources;
std::vector<uint64_t> nodes;
std::vector<uint64_t> ways;
std::vector<int64_t> ways;
std::vector<uint32_t> weight;
std::vector<float> speed;
std::unique_ptr<osrm::engine::api::fbresult::MetadataT> metadata;
Expand Down Expand Up @@ -494,8 +494,8 @@ struct Annotation FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
const flatbuffers::Vector<uint64_t> *nodes() const {
return GetPointer<const flatbuffers::Vector<uint64_t> *>(VT_NODES);
}
const flatbuffers::Vector<uint64_t> *ways() const {
return GetPointer<const flatbuffers::Vector<uint64_t> *>(VT_WAYS);
const flatbuffers::Vector<int64_t> *ways() const {
return GetPointer<const flatbuffers::Vector<int64_t> *>(VT_WAYS);
}
const flatbuffers::Vector<uint32_t> *weight() const {
return GetPointer<const flatbuffers::Vector<uint32_t> *>(VT_WEIGHT);
Expand Down Expand Up @@ -546,7 +546,7 @@ struct AnnotationBuilder {
void add_nodes(flatbuffers::Offset<flatbuffers::Vector<uint64_t>> nodes) {
fbb_.AddOffset(Annotation::VT_NODES, nodes);
}
void add_ways(flatbuffers::Offset<flatbuffers::Vector<uint64_t>> ways) {
void add_ways(flatbuffers::Offset<flatbuffers::Vector<int64_t>> ways) {
fbb_.AddOffset(Annotation::VT_WAYS, ways);
}
void add_weight(flatbuffers::Offset<flatbuffers::Vector<uint32_t>> weight) {
Expand Down Expand Up @@ -576,7 +576,7 @@ inline flatbuffers::Offset<Annotation> CreateAnnotation(
flatbuffers::Offset<flatbuffers::Vector<uint32_t>> duration = 0,
flatbuffers::Offset<flatbuffers::Vector<uint32_t>> datasources = 0,
flatbuffers::Offset<flatbuffers::Vector<uint64_t>> nodes = 0,
flatbuffers::Offset<flatbuffers::Vector<uint64_t>> ways = 0,
flatbuffers::Offset<flatbuffers::Vector<int64_t>> ways = 0,
flatbuffers::Offset<flatbuffers::Vector<uint32_t>> weight = 0,
flatbuffers::Offset<flatbuffers::Vector<float>> speed = 0,
flatbuffers::Offset<osrm::engine::api::fbresult::Metadata> metadata = 0) {
Expand All @@ -598,15 +598,15 @@ inline flatbuffers::Offset<Annotation> CreateAnnotationDirect(
const std::vector<uint32_t> *duration = nullptr,
const std::vector<uint32_t> *datasources = nullptr,
const std::vector<uint64_t> *nodes = nullptr,
const std::vector<uint64_t> *ways = nullptr,
const std::vector<int64_t> *ways = nullptr,
const std::vector<uint32_t> *weight = nullptr,
const std::vector<float> *speed = nullptr,
flatbuffers::Offset<osrm::engine::api::fbresult::Metadata> metadata = 0) {
auto distance__ = distance ? _fbb.CreateVector<uint32_t>(*distance) : 0;
auto duration__ = duration ? _fbb.CreateVector<uint32_t>(*duration) : 0;
auto datasources__ = datasources ? _fbb.CreateVector<uint32_t>(*datasources) : 0;
auto nodes__ = nodes ? _fbb.CreateVector<uint64_t>(*nodes) : 0;
auto ways__ = ways ? _fbb.CreateVector<uint64_t>(*ways) : 0;
auto ways__ = ways ? _fbb.CreateVector<int64_t>(*ways) : 0;
auto weight__ = weight ? _fbb.CreateVector<uint32_t>(*weight) : 0;
auto speed__ = speed ? _fbb.CreateVector<float>(*speed) : 0;
return osrm::engine::api::fbresult::CreateAnnotation(
Expand Down
2 changes: 1 addition & 1 deletion include/engine/api/flatbuffers/route.fbs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ table Annotation {
duration: [uint];
datasources: [uint];
nodes: [ulong];
ways: [ulong];
ways: [long];
weight: [uint];
speed: [float];
metadata: Metadata;
Expand Down
6 changes: 3 additions & 3 deletions include/engine/api/route_api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -503,13 +503,13 @@ class RouteAPI : public BaseAPI
nodes.emplace_back(static_cast<uint64_t>(node_id));
}
}
std::vector<uint64_t> ways;
std::vector<int64_t> 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<uint64_t>(way_id));
ways.emplace_back(static_cast<int64_t>(way_id));
}
}
auto nodes_vector = fb_result.CreateVector(nodes);
Expand Down Expand Up @@ -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<std::uint64_t>(way_id));
ways.values.push_back(static_cast<std::int64_t>(way_id));
}
annotation.values["ways"] = std::move(ways);
}
Expand Down
4 changes: 3 additions & 1 deletion include/engine/datafacade/datafacade_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ class BaseDataFacade

using OSMWayForwardRange =
boost::iterator_range<extractor::SegmentDataView::SegmentOSMWayVector::const_iterator>;
using OSMWayReverseRange = boost::reversed_range<const OSMWayForwardRange>;
using OSMWayNegateForwardRange =
boost::transformed_range<std::negate<OSMWayIDDir>, const OSMWayForwardRange>;
using OSMWayReverseRange = boost::reversed_range<const OSMWayNegateForwardRange>;

using WeightForwardRange =
boost::iterator_range<extractor::SegmentDataView::SegmentWeightVector::const_iterator>;
Expand Down
13 changes: 11 additions & 2 deletions include/engine/guidance/assemble_geometry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
2 changes: 1 addition & 1 deletion include/engine/guidance/leg_geometry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ struct LegGeometry
// original OSM node IDs for each coordinate
std::vector<OSMNodeID> osm_node_ids;
// original OSM way IDs between every pair of nodes
std::vector<OSMWayID> osm_way_ids;
std::vector<OSMWayIDDir> osm_way_ids;

// Per-coordinate metadata
struct Annotation
Expand Down
2 changes: 1 addition & 1 deletion include/engine/internal_route_result.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion include/engine/routing_algorithms/routing_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ void annotatePath(const FacadeT &facade,

// datastructures to hold extracted data from geometry
std::vector<NodeID> id_vector;
std::vector<OSMWayID> osm_way_id_vector;
std::vector<OSMWayIDDir> osm_way_id_vector;
std::vector<SegmentWeight> weight_vector;
std::vector<SegmentDuration> duration_vector;
std::vector<DatasourceID> datasource_vector;
Expand Down
2 changes: 1 addition & 1 deletion include/extractor/node_based_edge.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<NodeID, NodeID>;
using OSMWayIDMap = std::map<OSMWayIDMapKey, OSMWayID>;
using OSMWayIDMap = std::map<OSMWayIDMapKey, OSMWayIDDir>;

// Flags describing the class of the road. This data is used during creation of graphs/guidance
// generation but is not available in annotation/navigation
Expand Down
12 changes: 9 additions & 3 deletions include/extractor/segment_data_container.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@

#include <boost/filesystem/path.hpp>
#include <boost/range/adaptor/reversed.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/iterator_range.hpp>

#include <unordered_map>

#include <functional>
#include <string>
#include <vector>

Expand Down Expand Up @@ -56,7 +58,7 @@ template <storage::Ownership Ownership> class SegmentDataContainerImpl
using DirectionalGeometryID = std::uint32_t;
using SegmentOffset = std::uint32_t;
using SegmentNodeVector = Vector<NodeID>;
using SegmentOSMWayVector = Vector<OSMWayID>;
using SegmentOSMWayVector = Vector<OSMWayIDDir>;
using SegmentWeightVector = PackedVector<SegmentWeight, SEGMENT_WEIGHT_BITS>;
using SegmentDurationVector = PackedVector<SegmentDuration, SEGMENT_DURATION_BITS>;
using SegmentDatasourceVector = Vector<DatasourceID>;
Expand Down Expand Up @@ -102,7 +104,9 @@ template <storage::Ownership Ownership> 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<OSMWayIDDir>()));
}

auto GetForwardDurations(const DirectionalGeometryID id)
Expand Down Expand Up @@ -176,7 +180,9 @@ template <storage::Ownership Ownership> 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<OSMWayIDDir>()));
}

auto GetForwardDurations(const DirectionalGeometryID id) const
Expand Down
2 changes: 1 addition & 1 deletion include/storage/view_factory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<OSMWayID>(index, name + "/osm_ways");
auto osm_way_list = make_vector_view<OSMWayIDDir>(index, name + "/osm_ways");

extractor::SegmentDataView::SegmentWeightVector fwd_weight_list(
make_vector_view<extractor::SegmentDataView::SegmentWeightVector::block_type>(
Expand Down
1 change: 1 addition & 0 deletions include/util/typedefs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ using OSMNodeID = osrm::Alias<std::uint64_t, tag::osm_node_id>;
static_assert(std::is_pod<OSMNodeID>(), "OSMNodeID is not a valid alias");
using OSMWayID = osrm::Alias<std::uint64_t, tag::osm_way_id>;
static_assert(std::is_pod<OSMWayID>(), "OSMWayID is not a valid alias");
using OSMWayIDDir = std::int64_t;

using DuplicatedNodeID = std::uint64_t;
using RestrictionID = std::uint64_t;
Expand Down
26 changes: 11 additions & 15 deletions src/extractor/compressed_edge_container.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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
{
Expand All @@ -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
{
Expand Down
28 changes: 26 additions & 2 deletions src/extractor/extractor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
17 changes: 11 additions & 6 deletions unit_tests/library/route.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,7 @@ BOOST_AUTO_TEST_CASE(test_manual_setting_of_annotations_property_new_api)
}

using NodePair = std::pair<osmium::unsigned_object_id_type, osmium::unsigned_object_id_type>;
using NodePairToWayIDMap = std::map<NodePair, osmium::unsigned_object_id_type>;
using NodePairToWayIDMap = std::map<NodePair, int64_t>;

NodePairToWayIDMap read_node_pair_to_way_id_map(osmium::io::Reader &osm)
{
Expand All @@ -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();
}
Expand Down Expand Up @@ -700,15 +700,20 @@ LonLatVector check_route_annotated_ways(std::vector<osrm::util::Coordinate> &coo
for (nodes_it++; nodes_it != nodes.cend(); nodes_it++, ways_it++)
{
osmium::unsigned_object_id_type second = nodes_it->get<json::Number>().value;
osmium::unsigned_object_id_type way_id = ways_it->get<json::Number>().value;
int64_t way_id = ways_it->get<json::Number>().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;
}
Expand Down
2 changes: 1 addition & 1 deletion unit_tests/mocks/mock_datafacade.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
Expand Down

0 comments on commit d946025

Please sign in to comment.