streamline branch-and-bound query code in R-tree
This commit is contained in:
parent
8f6077e973
commit
df3a7676eb
@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "../Util/MercatorUtil.h"
|
#include "../Util/MercatorUtil.h"
|
||||||
#include "../Util/OSRMException.h"
|
#include "../Util/OSRMException.h"
|
||||||
#include "../Util/SimpleLogger.h"
|
#include "../Util/SimpleLogger.h"
|
||||||
|
#include "../Util/TimingUtil.h"
|
||||||
#include "../typedefs.h"
|
#include "../typedefs.h"
|
||||||
|
|
||||||
#include <osrm/Coordinate.h>
|
#include <osrm/Coordinate.h>
|
||||||
@ -53,7 +54,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <chrono>
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
@ -218,15 +218,15 @@ class StaticRTree
|
|||||||
private:
|
private:
|
||||||
struct WrappedInputElement
|
struct WrappedInputElement
|
||||||
{
|
{
|
||||||
explicit WrappedInputElement(const uint32_t _array_index, const uint64_t _hilbert_value)
|
explicit WrappedInputElement(const uint64_t _hilbert_value, const uint32_t _array_index)
|
||||||
: m_array_index(_array_index), m_hilbert_value(_hilbert_value)
|
: m_hilbert_value(_hilbert_value), m_array_index(_array_index)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
WrappedInputElement() : m_array_index(UINT_MAX), m_hilbert_value(0) {}
|
WrappedInputElement() : m_hilbert_value(0), m_array_index(UINT_MAX) {}
|
||||||
|
|
||||||
uint32_t m_array_index;
|
|
||||||
uint64_t m_hilbert_value;
|
uint64_t m_hilbert_value;
|
||||||
|
uint32_t m_array_index;
|
||||||
|
|
||||||
inline bool operator<(const WrappedInputElement &other) const
|
inline bool operator<(const WrappedInputElement &other) const
|
||||||
{
|
{
|
||||||
@ -243,13 +243,13 @@ class StaticRTree
|
|||||||
|
|
||||||
struct QueryCandidate
|
struct QueryCandidate
|
||||||
{
|
{
|
||||||
explicit QueryCandidate(const uint32_t n_id, const float dist)
|
explicit QueryCandidate(const float dist, const uint32_t n_id)
|
||||||
: node_id(n_id), min_dist(dist)
|
: min_dist(dist), node_id(n_id)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
QueryCandidate() : node_id(UINT_MAX), min_dist(std::numeric_limits<float>::max()) {}
|
QueryCandidate() : min_dist(std::numeric_limits<float>::max()), node_id(UINT_MAX) {}
|
||||||
uint32_t node_id;
|
|
||||||
float min_dist;
|
float min_dist;
|
||||||
|
uint32_t node_id;
|
||||||
inline bool operator<(const QueryCandidate &other) const
|
inline bool operator<(const QueryCandidate &other) const
|
||||||
{
|
{
|
||||||
// Attn: this is reversed order. std::pq is a max pq!
|
// Attn: this is reversed order. std::pq is a max pq!
|
||||||
@ -277,7 +277,7 @@ class StaticRTree
|
|||||||
<< " edge elements build on-top of " << coordinate_list.size()
|
<< " edge elements build on-top of " << coordinate_list.size()
|
||||||
<< " coordinates";
|
<< " coordinates";
|
||||||
|
|
||||||
std::chrono::time_point<std::chrono::steady_clock> time0 = std::chrono::steady_clock::now();
|
TIMER_START(construction);
|
||||||
std::vector<WrappedInputElement> input_wrapper_vector(m_element_count);
|
std::vector<WrappedInputElement> input_wrapper_vector(m_element_count);
|
||||||
|
|
||||||
HilbertCode get_hilbert_number;
|
HilbertCode get_hilbert_number;
|
||||||
@ -422,10 +422,9 @@ class StaticRTree
|
|||||||
tree_node_file.write((char *)&m_search_tree[0], sizeof(TreeNode) * size_of_tree);
|
tree_node_file.write((char *)&m_search_tree[0], sizeof(TreeNode) * size_of_tree);
|
||||||
// close tree node file.
|
// close tree node file.
|
||||||
tree_node_file.close();
|
tree_node_file.close();
|
||||||
std::chrono::time_point<std::chrono::steady_clock> time1 = std::chrono::steady_clock::now();
|
|
||||||
std::chrono::duration<double> elapsed_seconds = time1 - time0;
|
TIMER_STOP(construction);
|
||||||
SimpleLogger().Write() << "finished r-tree construction in " << (elapsed_seconds.count())
|
SimpleLogger().Write() << "finished r-tree construction in " << TIMER_MSEC(construction)/1000. << " seconds";
|
||||||
<< " seconds";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read-only operation for queries
|
// Read-only operation for queries
|
||||||
@ -507,16 +506,13 @@ class StaticRTree
|
|||||||
const unsigned zoom_level)
|
const unsigned zoom_level)
|
||||||
{
|
{
|
||||||
bool ignore_tiny_components = (zoom_level <= 14);
|
bool ignore_tiny_components = (zoom_level <= 14);
|
||||||
DataT nearest_edge;
|
|
||||||
float min_dist = std::numeric_limits<float>::max();
|
float min_dist = std::numeric_limits<float>::max();
|
||||||
float min_max_dist = std::numeric_limits<float>::max();
|
float min_max_dist = std::numeric_limits<float>::max();
|
||||||
bool found_a_nearest_edge = false;
|
|
||||||
|
|
||||||
// initialize queue with root element
|
// initialize queue with root element
|
||||||
std::priority_queue<QueryCandidate> traversal_queue;
|
std::priority_queue<QueryCandidate> traversal_queue;
|
||||||
float current_min_dist =
|
traversal_queue.emplace(0.f, 0);
|
||||||
m_search_tree[0].minimum_bounding_rectangle.GetMinDist(input_coordinate);
|
|
||||||
traversal_queue.emplace(0, current_min_dist);
|
|
||||||
|
|
||||||
while (!traversal_queue.empty())
|
while (!traversal_queue.empty())
|
||||||
{
|
{
|
||||||
@ -550,9 +546,7 @@ class StaticRTree
|
|||||||
{
|
{
|
||||||
// found a new minimum
|
// found a new minimum
|
||||||
min_dist = current_minimum_distance;
|
min_dist = current_minimum_distance;
|
||||||
result_coordinate.lat = m_coordinate_list->at(current_edge.u).lat;
|
result_coordinate = m_coordinate_list->at(current_edge.u);
|
||||||
result_coordinate.lon = m_coordinate_list->at(current_edge.u).lon;
|
|
||||||
found_a_nearest_edge = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
current_minimum_distance =
|
current_minimum_distance =
|
||||||
@ -566,9 +560,7 @@ class StaticRTree
|
|||||||
{
|
{
|
||||||
// found a new minimum
|
// found a new minimum
|
||||||
min_dist = current_minimum_distance;
|
min_dist = current_minimum_distance;
|
||||||
result_coordinate.lat = m_coordinate_list->at(current_edge.v).lat;
|
result_coordinate = m_coordinate_list->at(current_edge.v);
|
||||||
result_coordinate.lon = m_coordinate_list->at(current_edge.v).lon;
|
|
||||||
found_a_nearest_edge = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -582,8 +574,7 @@ class StaticRTree
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return result_coordinate.isValid();
|
||||||
return found_a_nearest_edge;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
|
bool FindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
|
||||||
@ -595,19 +586,10 @@ class StaticRTree
|
|||||||
|
|
||||||
float min_dist = std::numeric_limits<float>::max();
|
float min_dist = std::numeric_limits<float>::max();
|
||||||
float min_max_dist = std::numeric_limits<float>::max();
|
float min_max_dist = std::numeric_limits<float>::max();
|
||||||
bool found_a_nearest_edge = false;
|
|
||||||
|
|
||||||
FixedPointCoordinate nearest, current_source_coordinate, current_target_coordinate;
|
|
||||||
|
|
||||||
std::priority_queue<QueryCandidate> traversal_queue;
|
std::priority_queue<QueryCandidate> traversal_queue;
|
||||||
traversal_queue.emplace(0, 0.f);
|
traversal_queue.emplace(0.f, 0);
|
||||||
// min_max_dist = std::min(min_max_dist, m_search_tree[0].minimum_bounding_rectangle.GetMinMaxDist(input_coordinate));
|
|
||||||
|
|
||||||
BOOST_ASSERT_MSG(std::numeric_limits<float>::epsilon() >
|
|
||||||
(0. - traversal_queue.top().min_dist),
|
|
||||||
"Root element in NN Search has min dist != 0.");
|
|
||||||
|
|
||||||
LeafNode current_leaf_node;
|
|
||||||
while (!traversal_queue.empty())
|
while (!traversal_queue.empty())
|
||||||
{
|
{
|
||||||
const QueryCandidate current_query_node = traversal_queue.top();
|
const QueryCandidate current_query_node = traversal_queue.top();
|
||||||
@ -620,6 +602,7 @@ class StaticRTree
|
|||||||
const TreeNode ¤t_tree_node = m_search_tree[current_query_node.node_id];
|
const TreeNode ¤t_tree_node = m_search_tree[current_query_node.node_id];
|
||||||
if (current_tree_node.child_is_on_disk)
|
if (current_tree_node.child_is_on_disk)
|
||||||
{
|
{
|
||||||
|
LeafNode current_leaf_node;
|
||||||
LoadLeafFromDisk(current_tree_node.children[0], current_leaf_node);
|
LoadLeafFromDisk(current_tree_node.children[0], current_leaf_node);
|
||||||
for (uint32_t i = 0; i < current_leaf_node.object_count; ++i)
|
for (uint32_t i = 0; i < current_leaf_node.object_count; ++i)
|
||||||
{
|
{
|
||||||
@ -630,6 +613,7 @@ class StaticRTree
|
|||||||
}
|
}
|
||||||
|
|
||||||
float current_ratio = 0.;
|
float current_ratio = 0.;
|
||||||
|
FixedPointCoordinate nearest;
|
||||||
const float current_perpendicular_distance =
|
const float current_perpendicular_distance =
|
||||||
FixedPointCoordinate::ComputePerpendicularDistance(
|
FixedPointCoordinate::ComputePerpendicularDistance(
|
||||||
m_coordinate_list->at(current_edge.u),
|
m_coordinate_list->at(current_edge.u),
|
||||||
@ -644,30 +628,17 @@ class StaticRTree
|
|||||||
!EpsilonCompare(current_perpendicular_distance, min_dist))
|
!EpsilonCompare(current_perpendicular_distance, min_dist))
|
||||||
{ // found a new minimum
|
{ // found a new minimum
|
||||||
min_dist = current_perpendicular_distance;
|
min_dist = current_perpendicular_distance;
|
||||||
// TODO: use assignment c'tor in PhantomNode
|
result_phantom_node = { current_edge.forward_edge_based_node_id,
|
||||||
result_phantom_node.forward_node_id =
|
current_edge.reverse_edge_based_node_id,
|
||||||
current_edge.forward_edge_based_node_id;
|
current_edge.name_id,
|
||||||
result_phantom_node.reverse_node_id =
|
current_edge.forward_weight,
|
||||||
current_edge.reverse_edge_based_node_id;
|
current_edge.reverse_weight,
|
||||||
result_phantom_node.name_id = current_edge.name_id;
|
current_edge.forward_offset,
|
||||||
result_phantom_node.forward_weight = current_edge.forward_weight;
|
current_edge.reverse_offset,
|
||||||
result_phantom_node.reverse_weight = current_edge.reverse_weight;
|
current_edge.packed_geometry_id,
|
||||||
result_phantom_node.forward_offset = current_edge.forward_offset;
|
nearest,
|
||||||
result_phantom_node.reverse_offset = current_edge.reverse_offset;
|
current_edge.fwd_segment_position};
|
||||||
result_phantom_node.packed_geometry_id =
|
|
||||||
current_edge.packed_geometry_id;
|
|
||||||
result_phantom_node.fwd_segment_position =
|
|
||||||
current_edge.fwd_segment_position;
|
|
||||||
|
|
||||||
result_phantom_node.location = nearest;
|
|
||||||
current_source_coordinate.lat =
|
|
||||||
m_coordinate_list->at(current_edge.u).lat;
|
|
||||||
current_source_coordinate.lon =
|
|
||||||
m_coordinate_list->at(current_edge.u).lon;
|
|
||||||
current_target_coordinate.lat = m_coordinate_list->at(current_edge.v).lat;
|
|
||||||
current_target_coordinate.lon = m_coordinate_list->at(current_edge.v).lon;
|
|
||||||
nearest_edge = current_edge;
|
nearest_edge = current_edge;
|
||||||
found_a_nearest_edge = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -682,22 +653,22 @@ class StaticRTree
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hack to fix rounding errors and wandering via nodes.
|
if (result_phantom_node.location.isValid())
|
||||||
if (1 == std::abs(input_coordinate.lon - result_phantom_node.location.lon))
|
|
||||||
{
|
{
|
||||||
result_phantom_node.location.lon = input_coordinate.lon;
|
// Hack to fix rounding errors and wandering via nodes.
|
||||||
}
|
if (1 == std::abs(input_coordinate.lon - result_phantom_node.location.lon))
|
||||||
if (1 == std::abs(input_coordinate.lat - result_phantom_node.location.lat))
|
{
|
||||||
{
|
result_phantom_node.location.lon = input_coordinate.lon;
|
||||||
result_phantom_node.location.lat = input_coordinate.lat;
|
}
|
||||||
}
|
if (1 == std::abs(input_coordinate.lat - result_phantom_node.location.lat))
|
||||||
|
{
|
||||||
|
result_phantom_node.location.lat = input_coordinate.lat;
|
||||||
|
}
|
||||||
|
|
||||||
if (found_a_nearest_edge)
|
|
||||||
{
|
|
||||||
const float distance_1 = FixedPointCoordinate::ApproximateEuclideanDistance(
|
const float distance_1 = FixedPointCoordinate::ApproximateEuclideanDistance(
|
||||||
current_source_coordinate, result_phantom_node.location);
|
m_coordinate_list->at(nearest_edge.u), result_phantom_node.location);
|
||||||
const float distance_2 = FixedPointCoordinate::ApproximateEuclideanDistance(
|
const float distance_2 = FixedPointCoordinate::ApproximateEuclideanDistance(
|
||||||
current_source_coordinate, current_target_coordinate);
|
m_coordinate_list->at(nearest_edge.u), m_coordinate_list->at(nearest_edge.v));
|
||||||
const float ratio = std::min(1.f, distance_1 / distance_2);
|
const float ratio = std::min(1.f, distance_1 / distance_2);
|
||||||
|
|
||||||
if (SPECIAL_NODEID != result_phantom_node.forward_node_id)
|
if (SPECIAL_NODEID != result_phantom_node.forward_node_id)
|
||||||
@ -709,7 +680,7 @@ class StaticRTree
|
|||||||
result_phantom_node.reverse_weight *= (1. - ratio);
|
result_phantom_node.reverse_weight *= (1. - ratio);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return found_a_nearest_edge;
|
return result_phantom_node.location.isValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -739,7 +710,7 @@ class StaticRTree
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
traversal_queue.emplace(child_id, lower_bound_to_element);
|
traversal_queue.emplace(lower_bound_to_element, child_id);
|
||||||
}
|
}
|
||||||
return new_min_max_dist;
|
return new_min_max_dist;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user