Make forward/reverse weight/offset calculated at query time,
rather than being cached in the StaticRTree. This means we can freely apply traffic data and not have stale values lying around. It reduces the size of the RTree on disk, at the expense of some additional data in RAM.
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
#include "contractor/contractor_config.hpp"
|
||||
#include "contractor/query_edge.hpp"
|
||||
#include "extractor/edge_based_edge.hpp"
|
||||
#include "extractor/edge_based_node.hpp"
|
||||
#include "util/static_graph.hpp"
|
||||
#include "util/deallocating_vector.hpp"
|
||||
#include "util/node_based_graph.hpp"
|
||||
@@ -22,7 +23,6 @@ namespace osrm
|
||||
namespace extractor
|
||||
{
|
||||
struct SpeedProfileProperties;
|
||||
struct EdgeBasedNode;
|
||||
struct EdgeBasedEdge;
|
||||
}
|
||||
namespace contractor
|
||||
@@ -66,7 +66,10 @@ class Contractor
|
||||
util::DeallocatingVector<extractor::EdgeBasedEdge> &edge_based_edge_list,
|
||||
const std::string &edge_segment_lookup_path,
|
||||
const std::string &edge_penalty_path,
|
||||
const std::string &segment_speed_path);
|
||||
const std::string &segment_speed_path,
|
||||
const std::string &nodes_filename,
|
||||
const std::string &geometry_filename,
|
||||
const std::string &rtree_leaf_filename);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@ struct ContractorConfig
|
||||
edge_segment_lookup_path = osrm_input_path.string() + ".edge_segment_lookup";
|
||||
edge_penalty_path = osrm_input_path.string() + ".edge_penalties";
|
||||
node_based_graph_path = osrm_input_path.string() + ".nodes";
|
||||
geometry_path = osrm_input_path.string() + ".geometry";
|
||||
rtree_leaf_path = osrm_input_path.string() + ".fileIndex";
|
||||
}
|
||||
|
||||
boost::filesystem::path config_file_path;
|
||||
@@ -37,6 +39,8 @@ struct ContractorConfig
|
||||
std::string edge_segment_lookup_path;
|
||||
std::string edge_penalty_path;
|
||||
std::string node_based_graph_path;
|
||||
std::string geometry_path;
|
||||
std::string rtree_leaf_path;
|
||||
bool use_cached_priority;
|
||||
|
||||
unsigned requested_num_threads;
|
||||
|
||||
@@ -69,8 +69,13 @@ template <class EdgeDataT> class BaseDataFacade
|
||||
|
||||
virtual unsigned GetGeometryIndexForEdgeID(const unsigned id) const = 0;
|
||||
|
||||
virtual void GetUncompressedGeometry(const unsigned id,
|
||||
std::vector<unsigned> &result_nodes) const = 0;
|
||||
virtual void GetUncompressedGeometry(const EdgeID id,
|
||||
std::vector<NodeID> &result_nodes) const = 0;
|
||||
|
||||
// Gets the weight values for each segment in an uncompressed geometry.
|
||||
// Should always be 1 shorter than GetUncompressedGeometry
|
||||
virtual void GetUncompressedWeights(const EdgeID id,
|
||||
std::vector<EdgeWeight> &result_weights) const = 0;
|
||||
|
||||
virtual extractor::TurnInstruction GetTurnInstructionForEdgeID(const unsigned id) const = 0;
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "util/graph_loader.hpp"
|
||||
#include "util/simple_logger.hpp"
|
||||
#include "util/rectangle.hpp"
|
||||
#include "extractor/compressed_edge_container.hpp"
|
||||
|
||||
#include "osrm/coordinate.hpp"
|
||||
|
||||
@@ -55,7 +56,7 @@ template <class EdgeDataT> class InternalDataFacade final : public BaseDataFacad
|
||||
using RTreeLeaf = typename super::RTreeLeaf;
|
||||
using InternalRTree =
|
||||
util::StaticRTree<RTreeLeaf, util::ShM<util::FixedPointCoordinate, false>::vector, false>;
|
||||
using InternalGeospatialQuery = GeospatialQuery<InternalRTree>;
|
||||
using InternalGeospatialQuery = GeospatialQuery<InternalRTree, BaseDataFacade<EdgeDataT>>;
|
||||
|
||||
InternalDataFacade() {}
|
||||
|
||||
@@ -72,8 +73,9 @@ template <class EdgeDataT> class InternalDataFacade final : public BaseDataFacad
|
||||
util::ShM<char, false>::vector m_names_char_list;
|
||||
util::ShM<bool, false>::vector m_edge_is_compressed;
|
||||
util::ShM<unsigned, false>::vector m_geometry_indices;
|
||||
util::ShM<unsigned, false>::vector m_geometry_list;
|
||||
util::ShM<extractor::CompressedEdgeContainer::CompressedEdge, false>::vector m_geometry_list;
|
||||
util::ShM<bool, false>::vector m_is_core_node;
|
||||
util::ShM<unsigned, false>::vector m_segment_weights;
|
||||
|
||||
boost::thread_specific_ptr<InternalRTree> m_static_rtree;
|
||||
boost::thread_specific_ptr<InternalGeospatialQuery> m_geospatial_query;
|
||||
@@ -220,7 +222,7 @@ template <class EdgeDataT> class InternalDataFacade final : public BaseDataFacad
|
||||
if (number_of_compressed_geometries > 0)
|
||||
{
|
||||
geometry_stream.read((char *)&(m_geometry_list[0]),
|
||||
number_of_compressed_geometries * sizeof(unsigned));
|
||||
number_of_compressed_geometries * sizeof(extractor::CompressedEdgeContainer::CompressedEdge));
|
||||
}
|
||||
geometry_stream.close();
|
||||
}
|
||||
@@ -230,7 +232,7 @@ template <class EdgeDataT> class InternalDataFacade final : public BaseDataFacad
|
||||
BOOST_ASSERT_MSG(!m_coordinate_list->empty(), "coordinates must be loaded before r-tree");
|
||||
|
||||
m_static_rtree.reset(new InternalRTree(ram_index_path, file_index_path, m_coordinate_list));
|
||||
m_geospatial_query.reset(new InternalGeospatialQuery(*m_static_rtree, m_coordinate_list));
|
||||
m_geospatial_query.reset(new InternalGeospatialQuery(*m_static_rtree, m_coordinate_list, *this));
|
||||
}
|
||||
|
||||
void LoadStreetNames(const boost::filesystem::path &names_file)
|
||||
@@ -464,15 +466,27 @@ template <class EdgeDataT> class InternalDataFacade final : public BaseDataFacad
|
||||
}
|
||||
}
|
||||
|
||||
virtual void GetUncompressedGeometry(const unsigned id,
|
||||
std::vector<unsigned> &result_nodes) const override final
|
||||
virtual void GetUncompressedGeometry(const EdgeID id,
|
||||
std::vector<NodeID> &result_nodes) const override final
|
||||
{
|
||||
const unsigned begin = m_geometry_indices.at(id);
|
||||
const unsigned end = m_geometry_indices.at(id + 1);
|
||||
|
||||
result_nodes.clear();
|
||||
result_nodes.insert(result_nodes.begin(), m_geometry_list.begin() + begin,
|
||||
m_geometry_list.begin() + end);
|
||||
result_nodes.reserve(end - begin);
|
||||
std::for_each(m_geometry_list.begin() + begin, m_geometry_list.begin() + end, [&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge){ result_nodes.emplace_back(edge.node_id); });
|
||||
}
|
||||
|
||||
virtual void GetUncompressedWeights(const EdgeID id,
|
||||
std::vector<EdgeWeight> &result_weights) const override final
|
||||
{
|
||||
const unsigned begin = m_geometry_indices.at(id);
|
||||
const unsigned end = m_geometry_indices.at(id + 1);
|
||||
|
||||
result_weights.clear();
|
||||
result_weights.reserve(end - begin);
|
||||
std::for_each(m_geometry_list.begin() + begin, m_geometry_list.begin() + end, [&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge){ result_weights.emplace_back(edge.weight); });
|
||||
|
||||
}
|
||||
|
||||
std::string GetTimestamp() const override final { return m_timestamp; }
|
||||
|
||||
@@ -50,7 +50,7 @@ template <class EdgeDataT> class SharedDataFacade final : public BaseDataFacade<
|
||||
using RTreeLeaf = typename super::RTreeLeaf;
|
||||
using SharedRTree =
|
||||
util::StaticRTree<RTreeLeaf, util::ShM<util::FixedPointCoordinate, true>::vector, true>;
|
||||
using SharedGeospatialQuery = GeospatialQuery<SharedRTree>;
|
||||
using SharedGeospatialQuery = GeospatialQuery<SharedRTree, BaseDataFacade<EdgeDataT>>;
|
||||
using TimeStampedRTreePair = std::pair<unsigned, std::shared_ptr<SharedRTree>>;
|
||||
using RTreeNode = typename SharedRTree::TreeNode;
|
||||
|
||||
@@ -77,7 +77,7 @@ template <class EdgeDataT> class SharedDataFacade final : public BaseDataFacade<
|
||||
util::ShM<unsigned, true>::vector m_name_begin_indices;
|
||||
util::ShM<bool, true>::vector m_edge_is_compressed;
|
||||
util::ShM<unsigned, true>::vector m_geometry_indices;
|
||||
util::ShM<unsigned, true>::vector m_geometry_list;
|
||||
util::ShM<extractor::CompressedEdgeContainer::CompressedEdge, true>::vector m_geometry_list;
|
||||
util::ShM<bool, true>::vector m_is_core_node;
|
||||
|
||||
boost::thread_specific_ptr<std::pair<unsigned, std::shared_ptr<SharedRTree>>> m_static_rtree;
|
||||
@@ -115,7 +115,7 @@ template <class EdgeDataT> class SharedDataFacade final : public BaseDataFacade<
|
||||
tree_ptr, data_layout->num_entries[storage::SharedDataLayout::R_SEARCH_TREE],
|
||||
file_index_path, m_coordinate_list)));
|
||||
m_geospatial_query.reset(
|
||||
new SharedGeospatialQuery(*m_static_rtree->second, m_coordinate_list));
|
||||
new SharedGeospatialQuery(*m_static_rtree->second, m_coordinate_list, *this));
|
||||
}
|
||||
|
||||
void LoadGraph()
|
||||
@@ -221,9 +221,10 @@ template <class EdgeDataT> class SharedDataFacade final : public BaseDataFacade<
|
||||
data_layout->num_entries[storage::SharedDataLayout::GEOMETRIES_INDEX]);
|
||||
m_geometry_indices = std::move(geometry_begin_indices);
|
||||
|
||||
auto geometries_list_ptr = data_layout->GetBlockPtr<unsigned>(
|
||||
shared_memory, storage::SharedDataLayout::GEOMETRIES_LIST);
|
||||
typename util::ShM<unsigned, true>::vector geometry_list(
|
||||
auto geometries_list_ptr =
|
||||
data_layout->GetBlockPtr<extractor::CompressedEdgeContainer::CompressedEdge>(
|
||||
shared_memory, storage::SharedDataLayout::GEOMETRIES_LIST);
|
||||
typename util::ShM<extractor::CompressedEdgeContainer::CompressedEdge, true>::vector geometry_list(
|
||||
geometries_list_ptr,
|
||||
data_layout->num_entries[storage::SharedDataLayout::GEOMETRIES_LIST]);
|
||||
m_geometry_list = std::move(geometry_list);
|
||||
@@ -382,15 +383,27 @@ template <class EdgeDataT> class SharedDataFacade final : public BaseDataFacade<
|
||||
return m_edge_is_compressed.at(id);
|
||||
}
|
||||
|
||||
virtual void GetUncompressedGeometry(const unsigned id,
|
||||
std::vector<unsigned> &result_nodes) const override final
|
||||
virtual void GetUncompressedGeometry(const EdgeID id,
|
||||
std::vector<NodeID> &result_nodes) const override final
|
||||
{
|
||||
const unsigned begin = m_geometry_indices.at(id);
|
||||
const unsigned end = m_geometry_indices.at(id + 1);
|
||||
|
||||
result_nodes.clear();
|
||||
result_nodes.insert(result_nodes.begin(), m_geometry_list.begin() + begin,
|
||||
m_geometry_list.begin() + end);
|
||||
result_nodes.reserve(end - begin);
|
||||
std::for_each(m_geometry_list.begin() + begin, m_geometry_list.begin() + end, [&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge){ result_nodes.emplace_back(edge.node_id); });
|
||||
}
|
||||
|
||||
virtual void GetUncompressedWeights(const EdgeID id,
|
||||
std::vector<EdgeWeight> &result_weights) const override final
|
||||
{
|
||||
const unsigned begin = m_geometry_indices.at(id);
|
||||
const unsigned end = m_geometry_indices.at(id + 1);
|
||||
|
||||
result_weights.clear();
|
||||
result_weights.reserve(end - begin);
|
||||
std::for_each(m_geometry_list.begin() + begin, m_geometry_list.begin() + end, [&](const osrm::extractor::CompressedEdgeContainer::CompressedEdge &edge){ result_weights.emplace_back(edge.weight); });
|
||||
|
||||
}
|
||||
|
||||
virtual unsigned GetGeometryIndexForEdgeID(const unsigned id) const override final
|
||||
|
||||
@@ -22,14 +22,14 @@ namespace engine
|
||||
// Implements complex queries on top of an RTree and builds PhantomNodes from it.
|
||||
//
|
||||
// Only holds a weak reference on the RTree!
|
||||
template <typename RTreeT> class GeospatialQuery
|
||||
template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
||||
{
|
||||
using EdgeData = typename RTreeT::EdgeData;
|
||||
using CoordinateList = typename RTreeT::CoordinateList;
|
||||
|
||||
public:
|
||||
GeospatialQuery(RTreeT &rtree_, std::shared_ptr<CoordinateList> coordinates_)
|
||||
: rtree(rtree_), coordinates(std::move(coordinates_))
|
||||
GeospatialQuery(RTreeT &rtree_, std::shared_ptr<CoordinateList> coordinates_, DataFacadeT &datafacade_)
|
||||
: rtree(rtree_), coordinates(std::move(coordinates_)), datafacade(datafacade_)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -150,19 +150,51 @@ template <typename RTreeT> class GeospatialQuery
|
||||
coordinates->at(data.u), coordinates->at(data.v), input_coordinate,
|
||||
point_on_segment, ratio);
|
||||
|
||||
auto transformed = PhantomNodeWithDistance{PhantomNode{data, point_on_segment},
|
||||
current_perpendicular_distance};
|
||||
// Find the node-based-edge that this belongs to, and directly
|
||||
// calculate the forward_weight, forward_offset, reverse_weight, reverse_offset
|
||||
|
||||
int forward_offset = 0, forward_weight = 0;
|
||||
int reverse_offset = 0, reverse_weight = 0;
|
||||
|
||||
if (data.forward_packed_geometry_id != SPECIAL_EDGEID) {
|
||||
std::vector<EdgeWeight> forward_weight_vector;
|
||||
datafacade.GetUncompressedWeights(data.forward_packed_geometry_id,
|
||||
forward_weight_vector);
|
||||
for (std::size_t i = 0; i < data.fwd_segment_position; i++)
|
||||
{
|
||||
forward_offset += forward_weight_vector[i];
|
||||
}
|
||||
forward_weight = forward_weight_vector[data.fwd_segment_position];
|
||||
}
|
||||
|
||||
if (data.reverse_packed_geometry_id != SPECIAL_EDGEID) {
|
||||
std::vector<EdgeWeight> reverse_weight_vector;
|
||||
datafacade.GetUncompressedWeights(data.reverse_packed_geometry_id,
|
||||
reverse_weight_vector);
|
||||
|
||||
//BOOST_ASSERT(reverse_weight_vector.size() == forward_weight_vector.size());
|
||||
BOOST_ASSERT(data.fwd_segment_position < reverse_weight_vector.size());
|
||||
|
||||
for (std::size_t i = 0; i < reverse_weight_vector.size() - data.fwd_segment_position - 1; i++)
|
||||
{
|
||||
reverse_offset += reverse_weight_vector[i];
|
||||
}
|
||||
reverse_weight = reverse_weight_vector[reverse_weight_vector.size() -
|
||||
data.fwd_segment_position - 1];
|
||||
}
|
||||
|
||||
ratio = std::min(1.0, std::max(0.0, ratio));
|
||||
if (SPECIAL_NODEID != data.forward_edge_based_node_id) {
|
||||
forward_weight *= ratio;
|
||||
}
|
||||
if (SPECIAL_NODEID != data.reverse_edge_based_node_id) {
|
||||
reverse_weight *= 1.0 - ratio;
|
||||
}
|
||||
|
||||
auto transformed = PhantomNodeWithDistance{PhantomNode{data, forward_weight, forward_offset,
|
||||
reverse_weight, reverse_offset, point_on_segment},
|
||||
current_perpendicular_distance};
|
||||
|
||||
if (SPECIAL_NODEID != transformed.phantom_node.forward_node_id)
|
||||
{
|
||||
transformed.phantom_node.forward_weight *= ratio;
|
||||
}
|
||||
if (SPECIAL_NODEID != transformed.phantom_node.reverse_node_id)
|
||||
{
|
||||
transformed.phantom_node.reverse_weight *= 1.0 - ratio;
|
||||
}
|
||||
return transformed;
|
||||
}
|
||||
|
||||
@@ -190,6 +222,7 @@ template <typename RTreeT> class GeospatialQuery
|
||||
|
||||
RTreeT &rtree;
|
||||
const std::shared_ptr<CoordinateList> coordinates;
|
||||
DataFacadeT &datafacade;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,8 @@ struct PhantomNode
|
||||
int reverse_weight,
|
||||
int forward_offset,
|
||||
int reverse_offset,
|
||||
unsigned packed_geometry_id,
|
||||
unsigned forward_packed_geometry_id_,
|
||||
unsigned reverse_packed_geometry_id_,
|
||||
bool is_tiny_component,
|
||||
unsigned component_id,
|
||||
util::FixedPointCoordinate location,
|
||||
@@ -34,7 +35,9 @@ struct PhantomNode
|
||||
: forward_node_id(forward_node_id), reverse_node_id(reverse_node_id), name_id(name_id),
|
||||
forward_weight(forward_weight), reverse_weight(reverse_weight),
|
||||
forward_offset(forward_offset), reverse_offset(reverse_offset),
|
||||
packed_geometry_id(packed_geometry_id), component{component_id, is_tiny_component},
|
||||
forward_packed_geometry_id(forward_packed_geometry_id_),
|
||||
reverse_packed_geometry_id(reverse_packed_geometry_id_),
|
||||
component{component_id, is_tiny_component},
|
||||
location(std::move(location)), fwd_segment_position(fwd_segment_position),
|
||||
forward_travel_mode(forward_travel_mode), backward_travel_mode(backward_travel_mode)
|
||||
{
|
||||
@@ -44,7 +47,9 @@ struct PhantomNode
|
||||
: forward_node_id(SPECIAL_NODEID), reverse_node_id(SPECIAL_NODEID),
|
||||
name_id(std::numeric_limits<unsigned>::max()), forward_weight(INVALID_EDGE_WEIGHT),
|
||||
reverse_weight(INVALID_EDGE_WEIGHT), forward_offset(0), reverse_offset(0),
|
||||
packed_geometry_id(SPECIAL_EDGEID), component{INVALID_COMPONENTID, false},
|
||||
forward_packed_geometry_id(SPECIAL_EDGEID),
|
||||
reverse_packed_geometry_id(SPECIAL_EDGEID),
|
||||
component{INVALID_COMPONENTID, false},
|
||||
fwd_segment_position(0), forward_travel_mode(TRAVEL_MODE_INACCESSIBLE),
|
||||
backward_travel_mode(TRAVEL_MODE_INACCESSIBLE)
|
||||
{
|
||||
@@ -89,19 +94,20 @@ struct PhantomNode
|
||||
bool operator==(const PhantomNode &other) const { return location == other.location; }
|
||||
|
||||
template <class OtherT>
|
||||
PhantomNode(const OtherT &other, const util::FixedPointCoordinate foot_point)
|
||||
PhantomNode(const OtherT &other, int forward_weight_, int forward_offset_, int reverse_weight_, int reverse_offset_, const util::FixedPointCoordinate foot_point)
|
||||
{
|
||||
forward_node_id = other.forward_edge_based_node_id;
|
||||
reverse_node_id = other.reverse_edge_based_node_id;
|
||||
name_id = other.name_id;
|
||||
|
||||
forward_weight = other.forward_weight;
|
||||
reverse_weight = other.reverse_weight;
|
||||
forward_weight = forward_weight_;
|
||||
reverse_weight = reverse_weight_;
|
||||
|
||||
forward_offset = other.forward_offset;
|
||||
reverse_offset = other.reverse_offset;
|
||||
forward_offset = forward_offset_;
|
||||
reverse_offset = reverse_offset_;
|
||||
|
||||
packed_geometry_id = other.packed_geometry_id;
|
||||
forward_packed_geometry_id = other.forward_packed_geometry_id;
|
||||
reverse_packed_geometry_id = other.reverse_packed_geometry_id;
|
||||
|
||||
component.id = other.component.id;
|
||||
component.is_tiny = other.component.is_tiny;
|
||||
@@ -120,7 +126,8 @@ struct PhantomNode
|
||||
int reverse_weight;
|
||||
int forward_offset;
|
||||
int reverse_offset;
|
||||
unsigned packed_geometry_id;
|
||||
unsigned forward_packed_geometry_id;
|
||||
unsigned reverse_packed_geometry_id;
|
||||
struct ComponentType
|
||||
{
|
||||
uint32_t id : 31;
|
||||
@@ -139,7 +146,7 @@ struct PhantomNode
|
||||
};
|
||||
|
||||
#ifndef _MSC_VER
|
||||
static_assert(sizeof(PhantomNode) == 48, "PhantomNode has more padding then expected");
|
||||
static_assert(sizeof(PhantomNode) == 52, "PhantomNode has more padding then expected");
|
||||
#endif
|
||||
|
||||
using PhantomNodePair = std::pair<PhantomNode, PhantomNode>;
|
||||
@@ -172,7 +179,8 @@ inline std::ostream &operator<<(std::ostream &out, const PhantomNode &pn)
|
||||
<< "rev-w: " << pn.reverse_weight << ", "
|
||||
<< "fwd-o: " << pn.forward_offset << ", "
|
||||
<< "rev-o: " << pn.reverse_offset << ", "
|
||||
<< "geom: " << pn.packed_geometry_id << ", "
|
||||
<< "fwd_geom: " << pn.forward_packed_geometry_id << ", "
|
||||
<< "rev_geom: " << pn.reverse_packed_geometry_id << ", "
|
||||
<< "comp: " << pn.component.is_tiny << " / " << pn.component.id << ", "
|
||||
<< "pos: " << pn.fwd_segment_position << ", "
|
||||
<< "loc: " << pn.location;
|
||||
|
||||
@@ -244,12 +244,34 @@ template <class DataFacadeT> class TilePlugin final : public BasePlugin
|
||||
// Get coordinates for start/end nodes of segmet (NodeIDs u and v)
|
||||
const auto a = facade->GetCoordinateOfNode(edge.u);
|
||||
const auto b = facade->GetCoordinateOfNode(edge.v);
|
||||
// Calculate the length in meters
|
||||
const double length = osrm::util::coordinate_calculation::haversineDistance(
|
||||
a.lon, a.lat, b.lon, b.lat);
|
||||
// Calculate the length in meters, using the same calculation used to set the
|
||||
// weight, so we can back-calculate the speed value that was set.
|
||||
const double length = osrm::util::coordinate_calculation::greatCircleDistance(
|
||||
a.lat, a.lon, b.lat, b.lon);
|
||||
|
||||
int forward_weight = 0;
|
||||
int reverse_weight = 0;
|
||||
|
||||
if (edge.forward_packed_geometry_id != SPECIAL_EDGEID) {
|
||||
std::vector<EdgeWeight> forward_weight_vector;
|
||||
facade->GetUncompressedWeights(edge.forward_packed_geometry_id,
|
||||
forward_weight_vector);
|
||||
forward_weight = forward_weight_vector[edge.fwd_segment_position];
|
||||
}
|
||||
|
||||
if (edge.reverse_packed_geometry_id != SPECIAL_EDGEID) {
|
||||
std::vector<EdgeWeight> reverse_weight_vector;
|
||||
facade->GetUncompressedWeights(edge.reverse_packed_geometry_id,
|
||||
reverse_weight_vector);
|
||||
|
||||
BOOST_ASSERT(edge.fwd_segment_position < reverse_weight_vector.size());
|
||||
|
||||
reverse_weight = reverse_weight_vector[reverse_weight_vector.size() -
|
||||
edge.fwd_segment_position - 1];
|
||||
}
|
||||
|
||||
// If this is a valid forward edge, go ahead and add it to the tile
|
||||
if (edge.forward_weight != 0 &&
|
||||
if (forward_weight != 0 &&
|
||||
edge.forward_edge_based_node_id != SPECIAL_NODEID)
|
||||
{
|
||||
std::int32_t start_x = 0;
|
||||
@@ -263,7 +285,7 @@ template <class DataFacadeT> class TilePlugin final : public BasePlugin
|
||||
|
||||
// Calculate the speed for this line
|
||||
std::uint32_t speed = static_cast<std::uint32_t>(
|
||||
round(length / edge.forward_weight * 10 * 3.6));
|
||||
round(length / forward_weight * 10 * 3.6));
|
||||
|
||||
line_type tile_line;
|
||||
for (auto const &pt : geo_line)
|
||||
@@ -315,7 +337,7 @@ template <class DataFacadeT> class TilePlugin final : public BasePlugin
|
||||
|
||||
// Repeat the above for the coordinates reversed and using the `reverse`
|
||||
// properties
|
||||
if (edge.reverse_weight != 0 &&
|
||||
if (reverse_weight != 0 &&
|
||||
edge.reverse_edge_based_node_id != SPECIAL_NODEID)
|
||||
{
|
||||
std::int32_t start_x = 0;
|
||||
@@ -328,7 +350,7 @@ template <class DataFacadeT> class TilePlugin final : public BasePlugin
|
||||
a.lat / COORDINATE_PRECISION);
|
||||
|
||||
const auto speed = static_cast<const std::uint32_t>(
|
||||
round(length / edge.forward_weight * 10 * 3.6));
|
||||
round(length / reverse_weight * 10 * 3.6));
|
||||
|
||||
line_type tile_line;
|
||||
for (auto const &pt : geo_line)
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <stack>
|
||||
#include <numeric>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
@@ -302,10 +303,20 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<unsigned> id_vector;
|
||||
std::vector<NodeID> id_vector;
|
||||
facade->GetUncompressedGeometry(facade->GetGeometryIndexForEdgeID(ed.id),
|
||||
id_vector);
|
||||
|
||||
std::vector<EdgeWeight> weight_vector;
|
||||
facade->GetUncompressedWeights(facade->GetGeometryIndexForEdgeID(ed.id),
|
||||
weight_vector);
|
||||
|
||||
int total_weight = std::accumulate(weight_vector.begin(), weight_vector.end(), 0);
|
||||
|
||||
BOOST_ASSERT(weight_vector.size() == id_vector.size());
|
||||
// ed.distance should be total_weight + penalties (turn, stop, etc)
|
||||
BOOST_ASSERT(ed.distance >= total_weight);
|
||||
|
||||
const std::size_t start_index =
|
||||
(unpacked_path.empty()
|
||||
? ((start_traversed_in_reverse)
|
||||
@@ -320,58 +331,57 @@ template <class DataFacadeT, class Derived> class BasicRoutingInterface
|
||||
for (std::size_t i = start_index; i < end_index; ++i)
|
||||
{
|
||||
unpacked_path.emplace_back(id_vector[i], name_index,
|
||||
extractor::TurnInstruction::NoTurn, 0,
|
||||
extractor::TurnInstruction::NoTurn, weight_vector[i],
|
||||
travel_mode);
|
||||
}
|
||||
unpacked_path.back().turn_instruction = turn_instruction;
|
||||
unpacked_path.back().segment_duration = ed.distance;
|
||||
unpacked_path.back().segment_duration += (ed.distance - total_weight);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (SPECIAL_EDGEID != phantom_node_pair.target_phantom.packed_geometry_id)
|
||||
std::vector<unsigned> id_vector;
|
||||
facade->GetUncompressedGeometry(phantom_node_pair.target_phantom.forward_packed_geometry_id,
|
||||
id_vector);
|
||||
const bool is_local_path = (phantom_node_pair.source_phantom.forward_packed_geometry_id ==
|
||||
phantom_node_pair.target_phantom.forward_packed_geometry_id) &&
|
||||
unpacked_path.empty();
|
||||
|
||||
std::cout << "Got id vector of size " << id_vector.size() << "\n";
|
||||
|
||||
std::size_t start_index = 0;
|
||||
if (is_local_path)
|
||||
{
|
||||
std::vector<unsigned> id_vector;
|
||||
facade->GetUncompressedGeometry(phantom_node_pair.target_phantom.packed_geometry_id,
|
||||
id_vector);
|
||||
const bool is_local_path = (phantom_node_pair.source_phantom.packed_geometry_id ==
|
||||
phantom_node_pair.target_phantom.packed_geometry_id) &&
|
||||
unpacked_path.empty();
|
||||
|
||||
std::size_t start_index = 0;
|
||||
if (is_local_path)
|
||||
{
|
||||
start_index = phantom_node_pair.source_phantom.fwd_segment_position;
|
||||
if (target_traversed_in_reverse)
|
||||
{
|
||||
start_index =
|
||||
id_vector.size() - phantom_node_pair.source_phantom.fwd_segment_position;
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t end_index = phantom_node_pair.target_phantom.fwd_segment_position;
|
||||
start_index = phantom_node_pair.source_phantom.fwd_segment_position;
|
||||
if (target_traversed_in_reverse)
|
||||
{
|
||||
std::reverse(id_vector.begin(), id_vector.end());
|
||||
end_index =
|
||||
id_vector.size() - phantom_node_pair.target_phantom.fwd_segment_position;
|
||||
start_index =
|
||||
id_vector.size() - phantom_node_pair.source_phantom.fwd_segment_position;
|
||||
}
|
||||
}
|
||||
|
||||
if (start_index > end_index)
|
||||
{
|
||||
start_index = std::min(start_index, id_vector.size() - 1);
|
||||
}
|
||||
std::size_t end_index = phantom_node_pair.target_phantom.fwd_segment_position;
|
||||
if (target_traversed_in_reverse)
|
||||
{
|
||||
std::reverse(id_vector.begin(), id_vector.end());
|
||||
end_index =
|
||||
id_vector.size() - phantom_node_pair.target_phantom.fwd_segment_position;
|
||||
}
|
||||
|
||||
for (std::size_t i = start_index; i != end_index; (start_index < end_index ? ++i : --i))
|
||||
{
|
||||
BOOST_ASSERT(i < id_vector.size());
|
||||
BOOST_ASSERT(phantom_node_pair.target_phantom.forward_travel_mode > 0);
|
||||
unpacked_path.emplace_back(
|
||||
PathData{id_vector[i], phantom_node_pair.target_phantom.name_id,
|
||||
extractor::TurnInstruction::NoTurn, 0,
|
||||
target_traversed_in_reverse
|
||||
? phantom_node_pair.target_phantom.backward_travel_mode
|
||||
: phantom_node_pair.target_phantom.forward_travel_mode});
|
||||
}
|
||||
if (start_index > end_index)
|
||||
{
|
||||
start_index = std::min(start_index, id_vector.size() - 1);
|
||||
}
|
||||
|
||||
for (std::size_t i = start_index; i != end_index; (start_index < end_index ? ++i : --i))
|
||||
{
|
||||
BOOST_ASSERT(i < id_vector.size());
|
||||
BOOST_ASSERT(phantom_node_pair.target_phantom.forward_travel_mode > 0);
|
||||
unpacked_path.emplace_back(
|
||||
PathData{id_vector[i], phantom_node_pair.target_phantom.name_id,
|
||||
extractor::TurnInstruction::NoTurn, 0,
|
||||
target_traversed_in_reverse
|
||||
? phantom_node_pair.target_phantom.backward_travel_mode
|
||||
: phantom_node_pair.target_phantom.forward_travel_mode});
|
||||
}
|
||||
|
||||
// there is no equivalent to a node-based node in an edge-expanded graph.
|
||||
|
||||
@@ -16,8 +16,13 @@ namespace extractor
|
||||
class CompressedEdgeContainer
|
||||
{
|
||||
public:
|
||||
using CompressedNode = std::pair<NodeID, EdgeWeight>;
|
||||
using EdgeBucket = std::vector<CompressedNode>;
|
||||
struct CompressedEdge
|
||||
{
|
||||
public:
|
||||
NodeID node_id; // refers to an internal node-based-node
|
||||
EdgeWeight weight; // the weight of the edge leading to this node
|
||||
};
|
||||
using EdgeBucket = std::vector<CompressedEdge>;
|
||||
|
||||
CompressedEdgeContainer();
|
||||
void CompressEdge(const EdgeID surviving_edge_id,
|
||||
@@ -27,6 +32,10 @@ class CompressedEdgeContainer
|
||||
const EdgeWeight weight1,
|
||||
const EdgeWeight weight2);
|
||||
|
||||
void AddUncompressedEdge(const EdgeID edgei_id,
|
||||
const NodeID target_node,
|
||||
const EdgeWeight weight);
|
||||
|
||||
bool HasEntryForID(const EdgeID edge_id) const;
|
||||
void PrintStatistics() const;
|
||||
void SerializeInternalVector(const std::string &path) const;
|
||||
|
||||
@@ -43,7 +43,7 @@ class EdgeBasedGraphFactory
|
||||
EdgeBasedGraphFactory &operator=(const EdgeBasedGraphFactory &) = delete;
|
||||
|
||||
explicit EdgeBasedGraphFactory(std::shared_ptr<util::NodeBasedDynamicGraph> node_based_graph,
|
||||
const CompressedEdgeContainer &compressed_edge_container,
|
||||
CompressedEdgeContainer &compressed_edge_container,
|
||||
const std::unordered_set<NodeID> &barrier_nodes,
|
||||
const std::unordered_set<NodeID> &traffic_lights,
|
||||
std::shared_ptr<const RestrictionMap> restriction_map,
|
||||
@@ -99,7 +99,7 @@ class EdgeBasedGraphFactory
|
||||
|
||||
const std::unordered_set<NodeID> &m_barrier_nodes;
|
||||
const std::unordered_set<NodeID> &m_traffic_lights;
|
||||
const CompressedEdgeContainer &m_compressed_edge_container;
|
||||
CompressedEdgeContainer &m_compressed_edge_container;
|
||||
|
||||
SpeedProfileProperties speed_profile;
|
||||
|
||||
|
||||
@@ -22,8 +22,8 @@ struct EdgeBasedNode
|
||||
EdgeBasedNode()
|
||||
: forward_edge_based_node_id(SPECIAL_NODEID), reverse_edge_based_node_id(SPECIAL_NODEID),
|
||||
u(SPECIAL_NODEID), v(SPECIAL_NODEID), name_id(0),
|
||||
forward_weight(INVALID_EDGE_WEIGHT >> 1), reverse_weight(INVALID_EDGE_WEIGHT >> 1),
|
||||
forward_offset(0), reverse_offset(0), packed_geometry_id(SPECIAL_EDGEID),
|
||||
forward_packed_geometry_id(SPECIAL_EDGEID),
|
||||
reverse_packed_geometry_id(SPECIAL_EDGEID),
|
||||
component{INVALID_COMPONENTID, false},
|
||||
fwd_segment_position(std::numeric_limits<unsigned short>::max()),
|
||||
forward_travel_mode(TRAVEL_MODE_INACCESSIBLE),
|
||||
@@ -36,11 +36,8 @@ struct EdgeBasedNode
|
||||
NodeID u,
|
||||
NodeID v,
|
||||
unsigned name_id,
|
||||
int forward_weight,
|
||||
int reverse_weight,
|
||||
int forward_offset,
|
||||
int reverse_offset,
|
||||
unsigned packed_geometry_id,
|
||||
unsigned forward_weight_or_packed_geometry_id_,
|
||||
unsigned reverse_weight_or_packed_geometry_id_,
|
||||
bool is_tiny_component,
|
||||
unsigned component_id,
|
||||
unsigned short fwd_segment_position,
|
||||
@@ -48,9 +45,9 @@ struct EdgeBasedNode
|
||||
TravelMode backward_travel_mode)
|
||||
: forward_edge_based_node_id(forward_edge_based_node_id),
|
||||
reverse_edge_based_node_id(reverse_edge_based_node_id), u(u), v(v), name_id(name_id),
|
||||
forward_weight(forward_weight), reverse_weight(reverse_weight),
|
||||
forward_offset(forward_offset), reverse_offset(reverse_offset),
|
||||
packed_geometry_id(packed_geometry_id), component{component_id, is_tiny_component},
|
||||
forward_packed_geometry_id(forward_weight_or_packed_geometry_id_),
|
||||
reverse_packed_geometry_id(reverse_weight_or_packed_geometry_id_),
|
||||
component{component_id, is_tiny_component},
|
||||
fwd_segment_position(fwd_segment_position), forward_travel_mode(forward_travel_mode),
|
||||
backward_travel_mode(backward_travel_mode)
|
||||
{
|
||||
@@ -68,18 +65,14 @@ struct EdgeBasedNode
|
||||
return centroid;
|
||||
}
|
||||
|
||||
bool IsCompressed() const { return packed_geometry_id != SPECIAL_EDGEID; }
|
||||
|
||||
NodeID forward_edge_based_node_id; // needed for edge-expanded graph
|
||||
NodeID reverse_edge_based_node_id; // needed for edge-expanded graph
|
||||
NodeID u; // indices into the coordinates array
|
||||
NodeID v; // indices into the coordinates array
|
||||
unsigned name_id; // id of the edge name
|
||||
int forward_weight; // weight of the edge
|
||||
int reverse_weight; // weight in the other direction (may be different)
|
||||
int forward_offset; // prefix sum of the weight up the edge TODO: short must suffice
|
||||
int reverse_offset; // prefix sum of the weight from the edge TODO: short must suffice
|
||||
unsigned packed_geometry_id; // if set, then the edge represents a packed geometry
|
||||
|
||||
unsigned forward_packed_geometry_id;
|
||||
unsigned reverse_packed_geometry_id;
|
||||
struct
|
||||
{
|
||||
unsigned id : 31;
|
||||
|
||||
@@ -59,6 +59,13 @@ class StaticRTree
|
||||
std::uint32_t children[BRANCHING_FACTOR];
|
||||
};
|
||||
|
||||
struct LeafNode
|
||||
{
|
||||
LeafNode() : object_count(0), objects() {}
|
||||
uint32_t object_count;
|
||||
std::array<EdgeDataT, LEAF_NODE_SIZE> objects;
|
||||
};
|
||||
|
||||
private:
|
||||
struct WrappedInputElement
|
||||
{
|
||||
@@ -79,13 +86,6 @@ class StaticRTree
|
||||
}
|
||||
};
|
||||
|
||||
struct LeafNode
|
||||
{
|
||||
LeafNode() : object_count(0), objects() {}
|
||||
std::uint32_t object_count;
|
||||
std::array<EdgeDataT, LEAF_NODE_SIZE> objects;
|
||||
};
|
||||
|
||||
using QueryNodeType = mapbox::util::variant<TreeNode, EdgeDataT>;
|
||||
struct QueryCandidate
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user