#5325 Return way ID with sign meaning direction

This commit is contained in:
Vsevolod Novikov 2021-02-22 22:14:08 +03:00
parent 44bc0a521e
commit d946025f39
17 changed files with 91 additions and 48 deletions

View File

@ -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]
}
```

View File

@ -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;
@ -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);
@ -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) {
@ -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) {
@ -598,7 +598,7 @@ 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) {
@ -606,7 +606,7 @@ inline flatbuffers::Offset<Annotation> CreateAnnotationDirect(
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(

View File

@ -10,7 +10,7 @@ table Annotation {
duration: [uint];
datasources: [uint];
nodes: [ulong];
ways: [ulong];
ways: [long];
weight: [uint];
speed: [float];
metadata: Metadata;

View File

@ -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);
@ -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);
}

View File

@ -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>;

View File

@ -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());

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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>
@ -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>;
@ -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)
@ -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

View File

@ -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>(

View File

@ -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;

View File

@ -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
{

View File

@ -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);

View File

@ -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)
{
@ -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<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;
}

View File

@ -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());
}