migrate DataStructures to C++11
This commit is contained in:
parent
6abbb06ff6
commit
e12ad48822
@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CONCURRENTQUEUE_H_
|
#ifndef CONCURRENT_QUEUE_H
|
||||||
#define CONCURRENTQUEUE_H_
|
#define CONCURRENT_QUEUE_H
|
||||||
|
|
||||||
#include "../typedefs.h"
|
#include "../typedefs.h"
|
||||||
|
|
||||||
@ -36,64 +36,59 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <boost/thread/mutex.hpp>
|
#include <boost/thread/mutex.hpp>
|
||||||
#include <boost/thread/thread.hpp>
|
#include <boost/thread/thread.hpp>
|
||||||
|
|
||||||
template<typename Data>
|
template <typename Data> class ConcurrentQueue
|
||||||
class ConcurrentQueue {
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ConcurrentQueue(const size_t max_size) : m_internal_queue(max_size) { }
|
explicit ConcurrentQueue(const size_t max_size) : m_internal_queue(max_size) {}
|
||||||
|
|
||||||
inline void push(const Data & data) {
|
inline void push(const Data &data)
|
||||||
|
{
|
||||||
boost::mutex::scoped_lock lock(m_mutex);
|
boost::mutex::scoped_lock lock(m_mutex);
|
||||||
m_not_full.wait(
|
m_not_full.wait(lock, boost::bind(&ConcurrentQueue<Data>::is_not_full, this));
|
||||||
lock,
|
|
||||||
boost::bind(&ConcurrentQueue<Data>::is_not_full, this)
|
|
||||||
);
|
|
||||||
m_internal_queue.push_back(data);
|
m_internal_queue.push_back(data);
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
m_not_empty.notify_one();
|
m_not_empty.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool empty() const {
|
inline bool empty() const { return m_internal_queue.empty(); }
|
||||||
return m_internal_queue.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void wait_and_pop(Data & popped_value) {
|
inline void wait_and_pop(Data &popped_value)
|
||||||
|
{
|
||||||
boost::mutex::scoped_lock lock(m_mutex);
|
boost::mutex::scoped_lock lock(m_mutex);
|
||||||
m_not_empty.wait(
|
m_not_empty.wait(lock, boost::bind(&ConcurrentQueue<Data>::is_not_empty, this));
|
||||||
lock,
|
|
||||||
boost::bind(&ConcurrentQueue<Data>::is_not_empty, this)
|
|
||||||
);
|
|
||||||
popped_value = m_internal_queue.front();
|
popped_value = m_internal_queue.front();
|
||||||
m_internal_queue.pop_front();
|
m_internal_queue.pop_front();
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
m_not_full.notify_one();
|
m_not_full.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool try_pop(Data& popped_value) {
|
inline bool try_pop(Data &popped_value)
|
||||||
|
{
|
||||||
boost::mutex::scoped_lock lock(m_mutex);
|
boost::mutex::scoped_lock lock(m_mutex);
|
||||||
if(m_internal_queue.empty()) {
|
if (m_internal_queue.empty())
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
popped_value=m_internal_queue.front();
|
popped_value = m_internal_queue.front();
|
||||||
m_internal_queue.pop_front();
|
m_internal_queue.pop_front();
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
m_not_full.notify_one();
|
m_not_full.notify_one();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline bool is_not_empty() const {
|
inline bool is_not_empty() const { return !m_internal_queue.empty(); }
|
||||||
return !m_internal_queue.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool is_not_full() const {
|
inline bool is_not_full() const
|
||||||
|
{
|
||||||
return m_internal_queue.size() < m_internal_queue.capacity();
|
return m_internal_queue.size() < m_internal_queue.capacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::circular_buffer<Data> m_internal_queue;
|
boost::circular_buffer<Data> m_internal_queue;
|
||||||
boost::mutex m_mutex;
|
boost::mutex m_mutex;
|
||||||
boost::condition m_not_empty;
|
boost::condition m_not_empty;
|
||||||
boost::condition m_not_full;
|
boost::condition m_not_full;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* CONCURRENTQUEUE_H_ */
|
#endif // CONCURRENT_QUEUE_H
|
||||||
|
@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef DYNAMICGRAPH_H_INCLUDED
|
#ifndef DYNAMICGRAPH_H
|
||||||
#define DYNAMICGRAPH_H_INCLUDED
|
#define DYNAMICGRAPH_H
|
||||||
|
|
||||||
#include "../DataStructures/DeallocatingVector.h"
|
#include "../DataStructures/DeallocatingVector.h"
|
||||||
|
|
||||||
@ -38,211 +38,224 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <limits>
|
#include <limits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
template< typename EdgeDataT>
|
template <typename EdgeDataT> class DynamicGraph
|
||||||
class DynamicGraph {
|
{
|
||||||
public:
|
public:
|
||||||
typedef EdgeDataT EdgeData;
|
typedef EdgeDataT EdgeData;
|
||||||
typedef unsigned NodeIterator;
|
typedef unsigned NodeIterator;
|
||||||
typedef unsigned EdgeIterator;
|
typedef unsigned EdgeIterator;
|
||||||
|
|
||||||
class InputEdge {
|
class InputEdge
|
||||||
public:
|
{
|
||||||
NodeIterator source;
|
public:
|
||||||
NodeIterator target;
|
NodeIterator source;
|
||||||
EdgeDataT data;
|
NodeIterator target;
|
||||||
bool operator<( const InputEdge& right ) const {
|
EdgeDataT data;
|
||||||
if ( source != right.source )
|
bool operator<(const InputEdge &right) const
|
||||||
return source < right.source;
|
{
|
||||||
return target < right.target;
|
if (source != right.source)
|
||||||
}
|
return source < right.source;
|
||||||
};
|
return target < right.target;
|
||||||
|
|
||||||
//Constructs an empty graph with a given number of nodes.
|
|
||||||
explicit DynamicGraph( int32_t nodes ) : m_numNodes(nodes), m_numEdges(0) {
|
|
||||||
m_nodes.reserve( m_numNodes );
|
|
||||||
m_nodes.resize( m_numNodes );
|
|
||||||
|
|
||||||
m_edges.reserve( m_numNodes * 1.1 );
|
|
||||||
m_edges.resize( m_numNodes );
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<class ContainerT>
|
// Constructs an empty graph with a given number of nodes.
|
||||||
DynamicGraph( const int32_t nodes, const ContainerT &graph ) {
|
explicit DynamicGraph(int32_t nodes) : m_numNodes(nodes), m_numEdges(0)
|
||||||
m_numNodes = nodes;
|
{
|
||||||
m_numEdges = ( EdgeIterator ) graph.size();
|
m_nodes.reserve(m_numNodes);
|
||||||
m_nodes.reserve( m_numNodes +1);
|
m_nodes.resize(m_numNodes);
|
||||||
m_nodes.resize( m_numNodes +1);
|
|
||||||
EdgeIterator edge = 0;
|
m_edges.reserve(m_numNodes * 1.1);
|
||||||
EdgeIterator position = 0;
|
m_edges.resize(m_numNodes);
|
||||||
for ( NodeIterator node = 0; node < m_numNodes; ++node ) {
|
}
|
||||||
EdgeIterator lastEdge = edge;
|
|
||||||
while ( edge < m_numEdges && graph[edge].source == node ) {
|
template <class ContainerT> DynamicGraph(const int32_t nodes, const ContainerT &graph)
|
||||||
++edge;
|
{
|
||||||
}
|
m_numNodes = nodes;
|
||||||
m_nodes[node].firstEdge = position;
|
m_numEdges = (EdgeIterator)graph.size();
|
||||||
m_nodes[node].edges = edge - lastEdge;
|
m_nodes.reserve(m_numNodes + 1);
|
||||||
position += m_nodes[node].edges;
|
m_nodes.resize(m_numNodes + 1);
|
||||||
|
EdgeIterator edge = 0;
|
||||||
|
EdgeIterator position = 0;
|
||||||
|
for (NodeIterator node = 0; node < m_numNodes; ++node)
|
||||||
|
{
|
||||||
|
EdgeIterator lastEdge = edge;
|
||||||
|
while (edge < m_numEdges && graph[edge].source == node)
|
||||||
|
{
|
||||||
|
++edge;
|
||||||
}
|
}
|
||||||
m_nodes.back().firstEdge = position;
|
m_nodes[node].firstEdge = position;
|
||||||
m_edges.reserve( position * 1.1 );
|
m_nodes[node].edges = edge - lastEdge;
|
||||||
m_edges.resize( position );
|
position += m_nodes[node].edges;
|
||||||
edge = 0;
|
}
|
||||||
for ( NodeIterator node = 0; node < m_numNodes; ++node ) {
|
m_nodes.back().firstEdge = position;
|
||||||
for ( EdgeIterator i = m_nodes[node].firstEdge, e = m_nodes[node].firstEdge + m_nodes[node].edges; i != e; ++i ) {
|
m_edges.reserve(position * 1.1);
|
||||||
m_edges[i].target = graph[edge].target;
|
m_edges.resize(position);
|
||||||
m_edges[i].data = graph[edge].data;
|
edge = 0;
|
||||||
BOOST_ASSERT_MSG(
|
for (NodeIterator node = 0; node < m_numNodes; ++node)
|
||||||
graph[edge].data.distance > 0,
|
{
|
||||||
"edge distance invalid"
|
for (EdgeIterator i = m_nodes[node].firstEdge,
|
||||||
);
|
e = m_nodes[node].firstEdge + m_nodes[node].edges;
|
||||||
++edge;
|
i != e;
|
||||||
|
++i)
|
||||||
|
{
|
||||||
|
m_edges[i].target = graph[edge].target;
|
||||||
|
m_edges[i].data = graph[edge].data;
|
||||||
|
BOOST_ASSERT_MSG(graph[edge].data.distance > 0, "edge distance invalid");
|
||||||
|
++edge;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~DynamicGraph() {}
|
||||||
|
|
||||||
|
unsigned GetNumberOfNodes() const { return m_numNodes; }
|
||||||
|
|
||||||
|
unsigned GetNumberOfEdges() const { return m_numEdges; }
|
||||||
|
|
||||||
|
unsigned GetOutDegree(const NodeIterator n) const { return m_nodes[n].edges; }
|
||||||
|
|
||||||
|
NodeIterator GetTarget(const EdgeIterator e) const { return NodeIterator(m_edges[e].target); }
|
||||||
|
|
||||||
|
void SetTarget(const EdgeIterator e, const NodeIterator n) { m_edges[e].target = n; }
|
||||||
|
|
||||||
|
EdgeDataT &GetEdgeData(const EdgeIterator e) { return m_edges[e].data; }
|
||||||
|
|
||||||
|
const EdgeDataT &GetEdgeData(const EdgeIterator e) const { return m_edges[e].data; }
|
||||||
|
|
||||||
|
EdgeIterator BeginEdges(const NodeIterator n) const
|
||||||
|
{
|
||||||
|
return EdgeIterator(m_nodes[n].firstEdge);
|
||||||
|
}
|
||||||
|
|
||||||
|
EdgeIterator EndEdges(const NodeIterator n) const
|
||||||
|
{
|
||||||
|
return EdgeIterator(m_nodes[n].firstEdge + m_nodes[n].edges);
|
||||||
|
}
|
||||||
|
|
||||||
|
// adds an edge. Invalidates edge iterators for the source node
|
||||||
|
EdgeIterator InsertEdge(const NodeIterator from, const NodeIterator to, const EdgeDataT &data)
|
||||||
|
{
|
||||||
|
Node &node = m_nodes[from];
|
||||||
|
EdgeIterator newFirstEdge = node.edges + node.firstEdge;
|
||||||
|
if (newFirstEdge >= m_edges.size() || !isDummy(newFirstEdge))
|
||||||
|
{
|
||||||
|
if (node.firstEdge != 0 && isDummy(node.firstEdge - 1))
|
||||||
|
{
|
||||||
|
node.firstEdge--;
|
||||||
|
m_edges[node.firstEdge] = m_edges[node.firstEdge + node.edges];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EdgeIterator newFirstEdge = (EdgeIterator)m_edges.size();
|
||||||
|
unsigned newSize = node.edges * 1.1 + 2;
|
||||||
|
EdgeIterator requiredCapacity = newSize + m_edges.size();
|
||||||
|
EdgeIterator oldCapacity = m_edges.capacity();
|
||||||
|
if (requiredCapacity >= oldCapacity)
|
||||||
|
{
|
||||||
|
m_edges.reserve(requiredCapacity * 1.1);
|
||||||
}
|
}
|
||||||
|
m_edges.resize(m_edges.size() + newSize);
|
||||||
|
for (EdgeIterator i = 0; i < node.edges; ++i)
|
||||||
|
{
|
||||||
|
m_edges[newFirstEdge + i] = m_edges[node.firstEdge + i];
|
||||||
|
makeDummy(node.firstEdge + i);
|
||||||
|
}
|
||||||
|
for (EdgeIterator i = node.edges + 1; i < newSize; ++i)
|
||||||
|
makeDummy(newFirstEdge + i);
|
||||||
|
node.firstEdge = newFirstEdge;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Edge &edge = m_edges[node.firstEdge + node.edges];
|
||||||
|
edge.target = to;
|
||||||
|
edge.data = data;
|
||||||
|
++m_numEdges;
|
||||||
|
++node.edges;
|
||||||
|
return EdgeIterator(node.firstEdge + node.edges);
|
||||||
|
}
|
||||||
|
|
||||||
|
// removes an edge. Invalidates edge iterators for the source node
|
||||||
|
void DeleteEdge(const NodeIterator source, const EdgeIterator e)
|
||||||
|
{
|
||||||
|
Node &node = m_nodes[source];
|
||||||
|
#pragma omp atomic
|
||||||
|
--m_numEdges;
|
||||||
|
--node.edges;
|
||||||
|
BOOST_ASSERT(std::numeric_limits<unsigned>::max() != node.edges);
|
||||||
|
const unsigned last = node.firstEdge + node.edges;
|
||||||
|
BOOST_ASSERT(std::numeric_limits<unsigned>::max() != last);
|
||||||
|
// swap with last edge
|
||||||
|
m_edges[e] = m_edges[last];
|
||||||
|
makeDummy(last);
|
||||||
|
}
|
||||||
|
|
||||||
|
// removes all edges (source,target)
|
||||||
|
int32_t DeleteEdgesTo(const NodeIterator source, const NodeIterator target)
|
||||||
|
{
|
||||||
|
int32_t deleted = 0;
|
||||||
|
for (EdgeIterator i = BeginEdges(source), iend = EndEdges(source); i < iend - deleted; ++i)
|
||||||
|
{
|
||||||
|
if (m_edges[i].target == target)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
deleted++;
|
||||||
|
m_edges[i] = m_edges[iend - deleted];
|
||||||
|
makeDummy(iend - deleted);
|
||||||
|
} while (i < iend - deleted && m_edges[i].target == target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~DynamicGraph(){ }
|
#pragma omp atomic
|
||||||
|
m_numEdges -= deleted;
|
||||||
|
m_nodes[source].edges -= deleted;
|
||||||
|
|
||||||
unsigned GetNumberOfNodes() const {
|
return deleted;
|
||||||
return m_numNodes;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
unsigned GetNumberOfEdges() const {
|
// searches for a specific edge
|
||||||
return m_numEdges;
|
EdgeIterator FindEdge(const NodeIterator from, const NodeIterator to) const
|
||||||
}
|
{
|
||||||
|
for (EdgeIterator i = BeginEdges(from), iend = EndEdges(from); i != iend; ++i)
|
||||||
unsigned GetOutDegree( const NodeIterator n ) const {
|
{
|
||||||
return m_nodes[n].edges;
|
if (to == m_edges[i].target)
|
||||||
}
|
{
|
||||||
|
return i;
|
||||||
NodeIterator GetTarget( const EdgeIterator e ) const {
|
|
||||||
return NodeIterator( m_edges[e].target );
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetTarget( const EdgeIterator e, const NodeIterator n ) {
|
|
||||||
m_edges[e].target = n;
|
|
||||||
}
|
|
||||||
|
|
||||||
EdgeDataT &GetEdgeData( const EdgeIterator e ) {
|
|
||||||
return m_edges[e].data;
|
|
||||||
}
|
|
||||||
|
|
||||||
const EdgeDataT &GetEdgeData( const EdgeIterator e ) const {
|
|
||||||
return m_edges[e].data;
|
|
||||||
}
|
|
||||||
|
|
||||||
EdgeIterator BeginEdges( const NodeIterator n ) const {
|
|
||||||
return EdgeIterator( m_nodes[n].firstEdge );
|
|
||||||
}
|
|
||||||
|
|
||||||
EdgeIterator EndEdges( const NodeIterator n ) const {
|
|
||||||
return EdgeIterator( m_nodes[n].firstEdge + m_nodes[n].edges );
|
|
||||||
}
|
|
||||||
|
|
||||||
//adds an edge. Invalidates edge iterators for the source node
|
|
||||||
EdgeIterator InsertEdge( const NodeIterator from, const NodeIterator to, const EdgeDataT &data ) {
|
|
||||||
Node &node = m_nodes[from];
|
|
||||||
EdgeIterator newFirstEdge = node.edges + node.firstEdge;
|
|
||||||
if ( newFirstEdge >= m_edges.size() || !isDummy( newFirstEdge ) ) {
|
|
||||||
if ( node.firstEdge != 0 && isDummy( node.firstEdge - 1 ) ) {
|
|
||||||
node.firstEdge--;
|
|
||||||
m_edges[node.firstEdge] = m_edges[node.firstEdge + node.edges];
|
|
||||||
} else {
|
|
||||||
EdgeIterator newFirstEdge = ( EdgeIterator ) m_edges.size();
|
|
||||||
unsigned newSize = node.edges * 1.1 + 2;
|
|
||||||
EdgeIterator requiredCapacity = newSize + m_edges.size();
|
|
||||||
EdgeIterator oldCapacity = m_edges.capacity();
|
|
||||||
if ( requiredCapacity >= oldCapacity ) {
|
|
||||||
m_edges.reserve( requiredCapacity * 1.1 );
|
|
||||||
}
|
|
||||||
m_edges.resize( m_edges.size() + newSize );
|
|
||||||
for ( EdgeIterator i = 0; i < node.edges; ++i ) {
|
|
||||||
m_edges[newFirstEdge + i ] = m_edges[node.firstEdge + i];
|
|
||||||
makeDummy( node.firstEdge + i );
|
|
||||||
}
|
|
||||||
for ( EdgeIterator i = node.edges + 1; i < newSize; ++i )
|
|
||||||
makeDummy( newFirstEdge + i );
|
|
||||||
node.firstEdge = newFirstEdge;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Edge &edge = m_edges[node.firstEdge + node.edges];
|
|
||||||
edge.target = to;
|
|
||||||
edge.data = data;
|
|
||||||
++m_numEdges;
|
|
||||||
++node.edges;
|
|
||||||
return EdgeIterator( node.firstEdge + node.edges );
|
|
||||||
}
|
}
|
||||||
|
return EndEdges(from);
|
||||||
|
}
|
||||||
|
|
||||||
//removes an edge. Invalidates edge iterators for the source node
|
protected:
|
||||||
void DeleteEdge( const NodeIterator source, const EdgeIterator e ) {
|
bool isDummy(const EdgeIterator edge) const
|
||||||
Node &node = m_nodes[source];
|
{
|
||||||
#pragma omp atomic
|
return m_edges[edge].target == (std::numeric_limits<NodeIterator>::max)();
|
||||||
--m_numEdges;
|
}
|
||||||
--node.edges;
|
|
||||||
BOOST_ASSERT(std::numeric_limits<unsigned>::max() != node.edges);
|
|
||||||
const unsigned last = node.firstEdge + node.edges;
|
|
||||||
BOOST_ASSERT( std::numeric_limits<unsigned>::max() != last);
|
|
||||||
//swap with last edge
|
|
||||||
m_edges[e] = m_edges[last];
|
|
||||||
makeDummy( last );
|
|
||||||
}
|
|
||||||
|
|
||||||
//removes all edges (source,target)
|
void makeDummy(const EdgeIterator edge)
|
||||||
int32_t DeleteEdgesTo( const NodeIterator source, const NodeIterator target ) {
|
{
|
||||||
int32_t deleted = 0;
|
m_edges[edge].target = (std::numeric_limits<NodeIterator>::max)();
|
||||||
for ( EdgeIterator i = BeginEdges( source ), iend = EndEdges( source ); i < iend - deleted; ++i ) {
|
}
|
||||||
if ( m_edges[i].target == target ) {
|
|
||||||
do {
|
|
||||||
deleted++;
|
|
||||||
m_edges[i] = m_edges[iend - deleted];
|
|
||||||
makeDummy( iend - deleted );
|
|
||||||
} while ( i < iend - deleted && m_edges[i].target == target );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma omp atomic
|
struct Node
|
||||||
m_numEdges -= deleted;
|
{
|
||||||
m_nodes[source].edges -= deleted;
|
// index of the first edge
|
||||||
|
EdgeIterator firstEdge;
|
||||||
|
// amount of edges
|
||||||
|
unsigned edges;
|
||||||
|
};
|
||||||
|
|
||||||
return deleted;
|
struct Edge
|
||||||
}
|
{
|
||||||
|
NodeIterator target;
|
||||||
|
EdgeDataT data;
|
||||||
|
};
|
||||||
|
|
||||||
//searches for a specific edge
|
NodeIterator m_numNodes;
|
||||||
EdgeIterator FindEdge( const NodeIterator from, const NodeIterator to ) const {
|
EdgeIterator m_numEdges;
|
||||||
for ( EdgeIterator i = BeginEdges( from ), iend = EndEdges( from ); i != iend; ++i ) {
|
|
||||||
if ( to == m_edges[i].target ) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return EndEdges( from );
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
std::vector<Node> m_nodes;
|
||||||
|
DeallocatingVector<Edge> m_edges;
|
||||||
bool isDummy( const EdgeIterator edge ) const {
|
|
||||||
return m_edges[edge].target == (std::numeric_limits< NodeIterator >::max)();
|
|
||||||
}
|
|
||||||
|
|
||||||
void makeDummy( const EdgeIterator edge ) {
|
|
||||||
m_edges[edge].target = (std::numeric_limits< NodeIterator >::max)();
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Node {
|
|
||||||
//index of the first edge
|
|
||||||
EdgeIterator firstEdge;
|
|
||||||
//amount of edges
|
|
||||||
unsigned edges;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Edge {
|
|
||||||
NodeIterator target;
|
|
||||||
EdgeDataT data;
|
|
||||||
};
|
|
||||||
|
|
||||||
NodeIterator m_numNodes;
|
|
||||||
EdgeIterator m_numEdges;
|
|
||||||
|
|
||||||
std::vector< Node > m_nodes;
|
|
||||||
DeallocatingVector< Edge > m_edges;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DYNAMICGRAPH_H_INCLUDED
|
#endif // DYNAMICGRAPH_H
|
||||||
|
@ -10,7 +10,8 @@
|
|||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
struct EdgeBasedNode {
|
struct EdgeBasedNode
|
||||||
|
{
|
||||||
|
|
||||||
EdgeBasedNode() :
|
EdgeBasedNode() :
|
||||||
forward_edge_based_node_id(SPECIAL_NODEID),
|
forward_edge_based_node_id(SPECIAL_NODEID),
|
||||||
@ -24,7 +25,7 @@ struct EdgeBasedNode {
|
|||||||
reverse_offset(0),
|
reverse_offset(0),
|
||||||
packed_geometry_id(SPECIAL_EDGEID),
|
packed_geometry_id(SPECIAL_EDGEID),
|
||||||
fwd_segment_position( std::numeric_limits<unsigned short>::max() ),
|
fwd_segment_position( std::numeric_limits<unsigned short>::max() ),
|
||||||
belongsToTinyComponent(false)
|
is_in_tiny_cc(false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
explicit EdgeBasedNode(
|
explicit EdgeBasedNode(
|
||||||
@ -52,18 +53,14 @@ struct EdgeBasedNode {
|
|||||||
reverse_offset(reverse_offset),
|
reverse_offset(reverse_offset),
|
||||||
packed_geometry_id(packed_geometry_id),
|
packed_geometry_id(packed_geometry_id),
|
||||||
fwd_segment_position(fwd_segment_position),
|
fwd_segment_position(fwd_segment_position),
|
||||||
belongsToTinyComponent(belongs_to_tiny_component)
|
is_in_tiny_cc(belongs_to_tiny_component)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(
|
BOOST_ASSERT((forward_edge_based_node_id != SPECIAL_NODEID) ||
|
||||||
( forward_edge_based_node_id != SPECIAL_NODEID ) ||
|
(reverse_edge_based_node_id != SPECIAL_NODEID));
|
||||||
( reverse_edge_based_node_id != SPECIAL_NODEID )
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FixedPointCoordinate Centroid(
|
static inline FixedPointCoordinate Centroid(const FixedPointCoordinate & a, const FixedPointCoordinate & b)
|
||||||
const FixedPointCoordinate & a,
|
{
|
||||||
const FixedPointCoordinate & b
|
|
||||||
) {
|
|
||||||
FixedPointCoordinate centroid;
|
FixedPointCoordinate centroid;
|
||||||
//The coordinates of the midpoint are given by:
|
//The coordinates of the midpoint are given by:
|
||||||
centroid.lat = (a.lat + b.lat)/2;
|
centroid.lat = (a.lat + b.lat)/2;
|
||||||
@ -71,7 +68,8 @@ struct EdgeBasedNode {
|
|||||||
return centroid;
|
return centroid;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsCompressed() {
|
bool IsCompressed() const
|
||||||
|
{
|
||||||
return packed_geometry_id != SPECIAL_EDGEID;
|
return packed_geometry_id != SPECIAL_EDGEID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,7 +84,7 @@ struct EdgeBasedNode {
|
|||||||
int reverse_offset; // prefix sum of the weight from 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 packed_geometry_id; // if set, then the edge represents a packed geometry
|
||||||
unsigned short fwd_segment_position; // segment id in a compressed geometry
|
unsigned short fwd_segment_position; // segment id in a compressed geometry
|
||||||
bool belongsToTinyComponent;
|
bool is_in_tiny_cc;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EDGE_BASED_NODE_H
|
#endif //EDGE_BASED_NODE_H
|
||||||
|
@ -33,15 +33,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
class NodeBasedEdge {
|
class NodeBasedEdge
|
||||||
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool operator< (const NodeBasedEdge& e) const {
|
bool operator<(const NodeBasedEdge &e) const
|
||||||
if (source() == e.source()) {
|
{
|
||||||
if (target() == e.target()) {
|
if (source() == e.source())
|
||||||
if (weight() == e.weight()) {
|
{
|
||||||
return (isForward() && isBackward() &&
|
if (target() == e.target())
|
||||||
((! e.isForward()) || (! e.isBackward())));
|
{
|
||||||
|
if (weight() == e.weight())
|
||||||
|
{
|
||||||
|
return (isForward() && isBackward() && ((!e.isForward()) || (!e.isBackward())));
|
||||||
}
|
}
|
||||||
return (weight() < e.weight());
|
return (weight() < e.weight());
|
||||||
}
|
}
|
||||||
@ -50,80 +54,77 @@ public:
|
|||||||
return (source() < e.source());
|
return (source() < e.source());
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit NodeBasedEdge(
|
explicit NodeBasedEdge(NodeID s,
|
||||||
NodeID s,
|
NodeID t,
|
||||||
NodeID t,
|
NodeID n,
|
||||||
NodeID n,
|
EdgeWeight w,
|
||||||
EdgeWeight w,
|
bool f,
|
||||||
bool f,
|
bool b,
|
||||||
bool b,
|
short ty,
|
||||||
short ty,
|
bool ra,
|
||||||
bool ra,
|
bool ig,
|
||||||
bool ig,
|
bool ar,
|
||||||
bool ar,
|
bool cf,
|
||||||
bool cf,
|
bool is_split)
|
||||||
bool is_split
|
: _source(s), _target(t), _name(n), _weight(w), _type(ty), forward(f), backward(b),
|
||||||
) : _source(s),
|
_roundabout(ra), _ignoreInGrid(ig), _accessRestricted(ar), _contraFlow(cf),
|
||||||
_target(t),
|
is_split(is_split)
|
||||||
_name(n),
|
|
||||||
_weight(w),
|
|
||||||
_type(ty),
|
|
||||||
forward(f),
|
|
||||||
backward(b),
|
|
||||||
_roundabout(ra),
|
|
||||||
_ignoreInGrid(ig),
|
|
||||||
_accessRestricted(ar),
|
|
||||||
_contraFlow(cf),
|
|
||||||
is_split(is_split)
|
|
||||||
{
|
{
|
||||||
if(ty < 0) {
|
if (ty < 0)
|
||||||
|
{
|
||||||
throw OSRMException("negative edge type");
|
throw OSRMException("negative edge type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeID target() const {return _target; }
|
NodeID target() const { return _target; }
|
||||||
NodeID source() const {return _source; }
|
NodeID source() const { return _source; }
|
||||||
NodeID name() const { return _name; }
|
NodeID name() const { return _name; }
|
||||||
EdgeWeight weight() const {return _weight; }
|
EdgeWeight weight() const { return _weight; }
|
||||||
short type() const {
|
short type() const
|
||||||
|
{
|
||||||
BOOST_ASSERT_MSG(_type >= 0, "type of ImportEdge invalid");
|
BOOST_ASSERT_MSG(_type >= 0, "type of ImportEdge invalid");
|
||||||
return _type; }
|
return _type;
|
||||||
bool isBackward() const { return backward; }
|
}
|
||||||
bool isForward() const { return forward; }
|
bool isBackward() const { return backward; }
|
||||||
bool isLocatable() const { return _type != 14; }
|
bool isForward() const { return forward; }
|
||||||
bool isRoundabout() const { return _roundabout; }
|
bool isLocatable() const { return _type != 14; }
|
||||||
bool ignoreInGrid() const { return _ignoreInGrid; }
|
bool isRoundabout() const { return _roundabout; }
|
||||||
bool isAccessRestricted() const { return _accessRestricted; }
|
bool ignoreInGrid() const { return _ignoreInGrid; }
|
||||||
bool isContraFlow() const { return _contraFlow; }
|
bool isAccessRestricted() const { return _accessRestricted; }
|
||||||
bool IsSplit() const { return is_split; }
|
bool isContraFlow() const { return _contraFlow; }
|
||||||
|
bool IsSplit() const { return is_split; }
|
||||||
|
|
||||||
//TODO: names need to be fixed.
|
// TODO: names need to be fixed.
|
||||||
NodeID _source;
|
NodeID _source;
|
||||||
NodeID _target;
|
NodeID _target;
|
||||||
NodeID _name;
|
NodeID _name;
|
||||||
EdgeWeight _weight;
|
EdgeWeight _weight;
|
||||||
short _type;
|
short _type;
|
||||||
bool forward:1;
|
bool forward : 1;
|
||||||
bool backward:1;
|
bool backward : 1;
|
||||||
bool _roundabout:1;
|
bool _roundabout : 1;
|
||||||
bool _ignoreInGrid:1;
|
bool _ignoreInGrid : 1;
|
||||||
bool _accessRestricted:1;
|
bool _accessRestricted : 1;
|
||||||
bool _contraFlow:1;
|
bool _contraFlow : 1;
|
||||||
bool is_split:1;
|
bool is_split : 1;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NodeBasedEdge() { }
|
NodeBasedEdge() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class EdgeBasedEdge {
|
class EdgeBasedEdge
|
||||||
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool operator< (const EdgeBasedEdge& e) const {
|
bool operator<(const EdgeBasedEdge &e) const
|
||||||
if (source() == e.source()) {
|
{
|
||||||
if (target() == e.target()) {
|
if (source() == e.source())
|
||||||
if (weight() == e.weight()) {
|
{
|
||||||
return (isForward() && isBackward() &&
|
if (target() == e.target())
|
||||||
((! e.isForward()) || (! e.isBackward())));
|
{
|
||||||
|
if (weight() == e.weight())
|
||||||
|
{
|
||||||
|
return (isForward() && isBackward() && ((!e.isForward()) || (!e.isBackward())));
|
||||||
}
|
}
|
||||||
return (weight() < e.weight());
|
return (weight() < e.weight());
|
||||||
}
|
}
|
||||||
@ -132,56 +133,44 @@ public:
|
|||||||
return (source() < e.source());
|
return (source() < e.source());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class EdgeT>
|
template <class EdgeT>
|
||||||
explicit EdgeBasedEdge(const EdgeT & myEdge ) :
|
explicit EdgeBasedEdge(const EdgeT &myEdge)
|
||||||
m_source(myEdge.source),
|
: m_source(myEdge.source), m_target(myEdge.target), m_edgeID(myEdge.data.via),
|
||||||
m_target(myEdge.target),
|
m_weight(myEdge.data.distance), m_forward(myEdge.data.forward),
|
||||||
m_edgeID(myEdge.data.via),
|
m_backward(myEdge.data.backward)
|
||||||
m_weight(myEdge.data.distance),
|
{
|
||||||
m_forward(myEdge.data.forward),
|
}
|
||||||
m_backward(myEdge.data.backward)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
/** Default constructor. target and weight are set to 0.*/
|
/** Default constructor. target and weight are set to 0.*/
|
||||||
EdgeBasedEdge() :
|
EdgeBasedEdge()
|
||||||
m_source(0),
|
: m_source(0), m_target(0), m_edgeID(0), m_weight(0), m_forward(false), m_backward(false)
|
||||||
m_target(0),
|
{
|
||||||
m_edgeID(0),
|
}
|
||||||
m_weight(0),
|
|
||||||
m_forward(false),
|
|
||||||
m_backward(false)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
explicit EdgeBasedEdge(
|
explicit EdgeBasedEdge(const NodeID s,
|
||||||
const NodeID s,
|
const NodeID t,
|
||||||
const NodeID t,
|
const NodeID v,
|
||||||
const NodeID v,
|
const EdgeWeight w,
|
||||||
const EdgeWeight w,
|
const bool f,
|
||||||
const bool f,
|
const bool b)
|
||||||
const bool b
|
: m_source(s), m_target(t), m_edgeID(v), m_weight(w), m_forward(f), m_backward(b)
|
||||||
) :
|
{
|
||||||
m_source(s),
|
}
|
||||||
m_target(t),
|
|
||||||
m_edgeID(v),
|
|
||||||
m_weight(w),
|
|
||||||
m_forward(f),
|
|
||||||
m_backward(b)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
NodeID target() const { return m_target; }
|
NodeID target() const { return m_target; }
|
||||||
NodeID source() const { return m_source; }
|
NodeID source() const { return m_source; }
|
||||||
EdgeWeight weight() const { return m_weight; }
|
EdgeWeight weight() const { return m_weight; }
|
||||||
NodeID id() const { return m_edgeID; }
|
NodeID id() const { return m_edgeID; }
|
||||||
bool isBackward() const { return m_backward; }
|
bool isBackward() const { return m_backward; }
|
||||||
bool isForward() const { return m_forward; }
|
bool isForward() const { return m_forward; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NodeID m_source;
|
NodeID m_source;
|
||||||
NodeID m_target;
|
NodeID m_target;
|
||||||
NodeID m_edgeID;
|
NodeID m_edgeID;
|
||||||
EdgeWeight m_weight:30;
|
EdgeWeight m_weight : 30;
|
||||||
bool m_forward:1;
|
bool m_forward : 1;
|
||||||
bool m_backward:1;
|
bool m_backward : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef NodeBasedEdge ImportEdge;
|
typedef NodeBasedEdge ImportEdge;
|
||||||
|
@ -31,55 +31,45 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "QueryNode.h"
|
#include "QueryNode.h"
|
||||||
#include "../DataStructures/HashTable.h"
|
#include "../DataStructures/HashTable.h"
|
||||||
|
|
||||||
|
struct ExternalMemoryNode : NodeInfo
|
||||||
struct ExternalMemoryNode : NodeInfo {
|
{
|
||||||
ExternalMemoryNode(
|
ExternalMemoryNode(int lat, int lon, unsigned int id, bool bollard, bool traffic_light)
|
||||||
int lat,
|
: NodeInfo(lat, lon, id), bollard(bollard), trafficLight(traffic_light)
|
||||||
int lon,
|
{
|
||||||
unsigned int id,
|
|
||||||
bool bollard,
|
|
||||||
bool traffic_light
|
|
||||||
) :
|
|
||||||
NodeInfo(lat, lon, id),
|
|
||||||
bollard(bollard),
|
|
||||||
trafficLight(traffic_light)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
ExternalMemoryNode()
|
|
||||||
:
|
|
||||||
bollard(false),
|
|
||||||
trafficLight(false)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
static ExternalMemoryNode min_value() {
|
|
||||||
return ExternalMemoryNode(0,0,0, false, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static ExternalMemoryNode max_value() {
|
ExternalMemoryNode() : bollard(false), trafficLight(false) {}
|
||||||
return ExternalMemoryNode(
|
|
||||||
std::numeric_limits<int>::max(),
|
static ExternalMemoryNode min_value() { return ExternalMemoryNode(0, 0, 0, false, false); }
|
||||||
std::numeric_limits<int>::max(),
|
|
||||||
std::numeric_limits<unsigned>::max(),
|
static ExternalMemoryNode max_value()
|
||||||
false,
|
{
|
||||||
false
|
return ExternalMemoryNode(std::numeric_limits<int>::max(),
|
||||||
);
|
std::numeric_limits<int>::max(),
|
||||||
|
std::numeric_limits<unsigned>::max(),
|
||||||
|
false,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeID key() const {
|
NodeID key() const { return id; }
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool bollard;
|
bool bollard;
|
||||||
bool trafficLight;
|
bool trafficLight;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ImportNode : public ExternalMemoryNode {
|
struct ImportNode : public ExternalMemoryNode
|
||||||
|
{
|
||||||
HashTable<std::string, std::string> keyVals;
|
HashTable<std::string, std::string> keyVals;
|
||||||
|
|
||||||
inline void Clear() {
|
inline void Clear()
|
||||||
keyVals.clear();
|
{
|
||||||
lat = 0; lon = 0; id = 0; bollard = false; trafficLight = false;
|
keyVals.clear();
|
||||||
}
|
lat = 0;
|
||||||
|
lon = 0;
|
||||||
|
id = 0;
|
||||||
|
bollard = false;
|
||||||
|
trafficLight = false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* IMPORTNODE_H_ */
|
#endif /* IMPORTNODE_H_ */
|
||||||
|
@ -25,80 +25,99 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef INPUT_READER_FACTORY_H
|
||||||
#ifndef INPUTREADERFACTORY_H
|
#define INPUT_READER_FACTORY_H
|
||||||
#define INPUTREADERFACTORY_H
|
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
#include <bzlib.h>
|
#include <bzlib.h>
|
||||||
#include <libxml/xmlreader.h>
|
#include <libxml/xmlreader.h>
|
||||||
|
|
||||||
struct BZ2Context {
|
struct BZ2Context
|
||||||
FILE* file;
|
{
|
||||||
BZFILE* bz2;
|
FILE *file;
|
||||||
|
BZFILE *bz2;
|
||||||
int error;
|
int error;
|
||||||
int nUnused;
|
int nUnused;
|
||||||
char unused[BZ_MAX_UNUSED];
|
char unused[BZ_MAX_UNUSED];
|
||||||
};
|
};
|
||||||
|
|
||||||
int readFromBz2Stream( void* pointer, char* buffer, int len ) {
|
int readFromBz2Stream(void *pointer, char *buffer, int len)
|
||||||
void *unusedTmpVoid=NULL;
|
{
|
||||||
char *unusedTmp=NULL;
|
void *unusedTmpVoid = NULL;
|
||||||
BZ2Context* context = (BZ2Context*) pointer;
|
char *unusedTmp = NULL;
|
||||||
|
BZ2Context *context = (BZ2Context *)pointer;
|
||||||
int read = 0;
|
int read = 0;
|
||||||
while(0 == read && !(BZ_STREAM_END == context->error && 0 == context->nUnused && feof(context->file))) {
|
while (0 == read &&
|
||||||
|
!(BZ_STREAM_END == context->error && 0 == context->nUnused && feof(context->file)))
|
||||||
|
{
|
||||||
read = BZ2_bzRead(&context->error, context->bz2, buffer, len);
|
read = BZ2_bzRead(&context->error, context->bz2, buffer, len);
|
||||||
if(BZ_OK == context->error) {
|
if (BZ_OK == context->error)
|
||||||
|
{
|
||||||
return read;
|
return read;
|
||||||
} else if(BZ_STREAM_END == context->error) {
|
}
|
||||||
|
else if (BZ_STREAM_END == context->error)
|
||||||
|
{
|
||||||
BZ2_bzReadGetUnused(&context->error, context->bz2, &unusedTmpVoid, &context->nUnused);
|
BZ2_bzReadGetUnused(&context->error, context->bz2, &unusedTmpVoid, &context->nUnused);
|
||||||
BOOST_ASSERT_MSG(BZ_OK == context->error, "Could not BZ2_bzReadGetUnused");
|
BOOST_ASSERT_MSG(BZ_OK == context->error, "Could not BZ2_bzReadGetUnused");
|
||||||
unusedTmp = (char*)unusedTmpVoid;
|
unusedTmp = (char *)unusedTmpVoid;
|
||||||
for(int i=0;i<context->nUnused;i++) {
|
for (int i = 0; i < context->nUnused; i++)
|
||||||
|
{
|
||||||
context->unused[i] = unusedTmp[i];
|
context->unused[i] = unusedTmp[i];
|
||||||
}
|
}
|
||||||
BZ2_bzReadClose(&context->error, context->bz2);
|
BZ2_bzReadClose(&context->error, context->bz2);
|
||||||
BOOST_ASSERT_MSG(BZ_OK == context->error, "Could not BZ2_bzReadClose");
|
BOOST_ASSERT_MSG(BZ_OK == context->error, "Could not BZ2_bzReadClose");
|
||||||
context->error = BZ_STREAM_END; // set to the stream end for next call to this function
|
context->error = BZ_STREAM_END; // set to the stream end for next call to this function
|
||||||
if(0 == context->nUnused && feof(context->file)) {
|
if (0 == context->nUnused && feof(context->file))
|
||||||
|
{
|
||||||
return read;
|
return read;
|
||||||
} else {
|
}
|
||||||
context->bz2 = BZ2_bzReadOpen(&context->error, context->file, 0, 0, context->unused, context->nUnused);
|
else
|
||||||
|
{
|
||||||
|
context->bz2 = BZ2_bzReadOpen(
|
||||||
|
&context->error, context->file, 0, 0, context->unused, context->nUnused);
|
||||||
BOOST_ASSERT_MSG(NULL != context->bz2, "Could not open file");
|
BOOST_ASSERT_MSG(NULL != context->bz2, "Could not open file");
|
||||||
}
|
}
|
||||||
} else { BOOST_ASSERT_MSG(false, "Could not read bz2 file"); }
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BOOST_ASSERT_MSG(false, "Could not read bz2 file");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return read;
|
return read;
|
||||||
}
|
}
|
||||||
|
|
||||||
int closeBz2Stream( void *pointer )
|
int closeBz2Stream(void *pointer)
|
||||||
{
|
{
|
||||||
BZ2Context* context = (BZ2Context*) pointer;
|
BZ2Context *context = (BZ2Context *)pointer;
|
||||||
fclose( context->file );
|
fclose(context->file);
|
||||||
delete context;
|
delete context;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
xmlTextReaderPtr inputReaderFactory( const char* name )
|
xmlTextReaderPtr inputReaderFactory(const char *name)
|
||||||
{
|
{
|
||||||
std::string inputName(name);
|
std::string inputName(name);
|
||||||
|
|
||||||
if(inputName.find(".osm.bz2")!=std::string::npos)
|
if (inputName.find(".osm.bz2") != std::string::npos)
|
||||||
{
|
{
|
||||||
BZ2Context* context = new BZ2Context();
|
BZ2Context *context = new BZ2Context();
|
||||||
context->error = false;
|
context->error = false;
|
||||||
context->file = fopen( name, "r" );
|
context->file = fopen(name, "r");
|
||||||
int error;
|
int error;
|
||||||
context->bz2 = BZ2_bzReadOpen( &error, context->file, 0, 0, context->unused, context->nUnused );
|
context->bz2 =
|
||||||
if ( context->bz2 == NULL || context->file == NULL ) {
|
BZ2_bzReadOpen(&error, context->file, 0, 0, context->unused, context->nUnused);
|
||||||
|
if (context->bz2 == NULL || context->file == NULL)
|
||||||
|
{
|
||||||
delete context;
|
delete context;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return xmlReaderForIO( readFromBz2Stream, closeBz2Stream, (void*) context, NULL, NULL, 0 );
|
return xmlReaderForIO(readFromBz2Stream, closeBz2Stream, (void *)context, NULL, NULL, 0);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
return xmlNewTextReaderFilename(name);
|
return xmlNewTextReaderFilename(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // INPUTREADERFACTORY_H
|
#endif // INPUT_READER_FACTORY_H
|
||||||
|
@ -29,61 +29,69 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#define LRUCACHE_H
|
#define LRUCACHE_H
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <boost/unordered_map.hpp>
|
#include <unordered_map>
|
||||||
|
|
||||||
template<typename KeyT, typename ValueT>
|
template <typename KeyT, typename ValueT> class LRUCache
|
||||||
class LRUCache {
|
{
|
||||||
private:
|
private:
|
||||||
struct CacheEntry {
|
struct CacheEntry
|
||||||
|
{
|
||||||
CacheEntry(KeyT k, ValueT v) : key(k), value(v) {}
|
CacheEntry(KeyT k, ValueT v) : key(k), value(v) {}
|
||||||
KeyT key;
|
KeyT key;
|
||||||
ValueT value;
|
ValueT value;
|
||||||
};
|
};
|
||||||
unsigned capacity;
|
unsigned capacity;
|
||||||
std::list<CacheEntry> itemsInCache;
|
std::list<CacheEntry> itemsInCache;
|
||||||
boost::unordered_map<KeyT, typename std::list<CacheEntry>::iterator > positionMap;
|
std::unordered_map<KeyT, typename std::list<CacheEntry>::iterator> positionMap;
|
||||||
public:
|
|
||||||
|
public:
|
||||||
explicit LRUCache(unsigned c) : capacity(c) {}
|
explicit LRUCache(unsigned c) : capacity(c) {}
|
||||||
|
|
||||||
bool Holds(KeyT key) {
|
bool Holds(KeyT key)
|
||||||
if(positionMap.find(key) != positionMap.end()) {
|
{
|
||||||
|
if (positionMap.find(key) != positionMap.end())
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Insert(const KeyT key, ValueT &value) {
|
void Insert(const KeyT key, ValueT &value)
|
||||||
|
{
|
||||||
itemsInCache.push_front(CacheEntry(key, value));
|
itemsInCache.push_front(CacheEntry(key, value));
|
||||||
positionMap.insert(std::make_pair(key, itemsInCache.begin()));
|
positionMap.insert(std::make_pair(key, itemsInCache.begin()));
|
||||||
if(itemsInCache.size() > capacity) {
|
if (itemsInCache.size() > capacity)
|
||||||
|
{
|
||||||
positionMap.erase(itemsInCache.back().key);
|
positionMap.erase(itemsInCache.back().key);
|
||||||
itemsInCache.pop_back();
|
itemsInCache.pop_back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Insert(const KeyT key, ValueT value) {
|
void Insert(const KeyT key, ValueT value)
|
||||||
|
{
|
||||||
itemsInCache.push_front(CacheEntry(key, value));
|
itemsInCache.push_front(CacheEntry(key, value));
|
||||||
positionMap.insert(std::make_pair(key, itemsInCache.begin()));
|
positionMap.insert(std::make_pair(key, itemsInCache.begin()));
|
||||||
if(itemsInCache.size() > capacity) {
|
if (itemsInCache.size() > capacity)
|
||||||
|
{
|
||||||
positionMap.erase(itemsInCache.back().key);
|
positionMap.erase(itemsInCache.back().key);
|
||||||
itemsInCache.pop_back();
|
itemsInCache.pop_back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Fetch(const KeyT key, ValueT& result) {
|
bool Fetch(const KeyT key, ValueT &result)
|
||||||
if(Holds(key)) {
|
{
|
||||||
|
if (Holds(key))
|
||||||
|
{
|
||||||
CacheEntry e = *(positionMap.find(key)->second);
|
CacheEntry e = *(positionMap.find(key)->second);
|
||||||
result = e.value;
|
result = e.value;
|
||||||
|
|
||||||
//move to front
|
// move to front
|
||||||
itemsInCache.splice(positionMap.find(key)->second, itemsInCache, itemsInCache.begin());
|
itemsInCache.splice(positionMap.find(key)->second, itemsInCache, itemsInCache.begin());
|
||||||
positionMap.find(key)->second = itemsInCache.begin();
|
positionMap.find(key)->second = itemsInCache.begin();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
unsigned Size() const {
|
unsigned Size() const { return itemsInCache.size(); }
|
||||||
return itemsInCache.size();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
#endif //LRUCACHE_H
|
#endif // LRUCACHE_H
|
||||||
|
@ -33,25 +33,23 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
struct OriginalEdgeData{
|
struct OriginalEdgeData
|
||||||
explicit OriginalEdgeData(
|
{
|
||||||
NodeID via_node,
|
explicit OriginalEdgeData(NodeID via_node,
|
||||||
unsigned name_id,
|
unsigned name_id,
|
||||||
TurnInstruction turn_instruction,
|
TurnInstruction turn_instruction,
|
||||||
bool compressed_geometry
|
bool compressed_geometry)
|
||||||
) :
|
: via_node(via_node), name_id(name_id), turn_instruction(turn_instruction),
|
||||||
via_node( via_node ),
|
compressed_geometry(compressed_geometry)
|
||||||
name_id( name_id ),
|
{
|
||||||
turn_instruction( turn_instruction ),
|
}
|
||||||
compressed_geometry( compressed_geometry )
|
|
||||||
{ }
|
|
||||||
|
|
||||||
OriginalEdgeData() :
|
OriginalEdgeData()
|
||||||
via_node( std::numeric_limits<unsigned>::max() ),
|
: via_node(std::numeric_limits<unsigned>::max()),
|
||||||
name_id( std::numeric_limits<unsigned>::max() ),
|
name_id(std::numeric_limits<unsigned>::max()),
|
||||||
turn_instruction( std::numeric_limits<unsigned char>::max() ),
|
turn_instruction(std::numeric_limits<unsigned char>::max()), compressed_geometry(false)
|
||||||
compressed_geometry( false )
|
{
|
||||||
{ }
|
}
|
||||||
|
|
||||||
NodeID via_node;
|
NodeID via_node;
|
||||||
unsigned name_id;
|
unsigned name_id;
|
||||||
@ -59,4 +57,4 @@ struct OriginalEdgeData{
|
|||||||
bool compressed_geometry;
|
bool compressed_geometry;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //ORIGINAL_EDGE_DATA_H
|
#endif // ORIGINAL_EDGE_DATA_H
|
||||||
|
@ -31,64 +31,68 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "../Util/OpenMPWrapper.h"
|
#include "../Util/OpenMPWrapper.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
class Percent {
|
class Percent
|
||||||
public:
|
{
|
||||||
/**
|
public:
|
||||||
* Constructor.
|
explicit Percent(unsigned max_value, unsigned step = 5) { reinit(max_value, step); }
|
||||||
* @param maxValue the value that corresponds to 100%
|
|
||||||
* @param step the progress is shown in steps of 'step' percent
|
// Reinitializes
|
||||||
*/
|
void reinit(unsigned max_value, unsigned step = 5)
|
||||||
explicit Percent(unsigned maxValue, unsigned step = 5) {
|
{
|
||||||
reinit(maxValue, step);
|
m_max_value = max_value;
|
||||||
|
m_current_value = 0;
|
||||||
|
m_percent_interval = m_max_value / 100;
|
||||||
|
m_next_threshold = m_percent_interval;
|
||||||
|
m_last_percent = 0;
|
||||||
|
m_step = step;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Reinitializes this object. */
|
// If there has been significant progress, display it.
|
||||||
void reinit(unsigned maxValue, unsigned step = 5) {
|
void printStatus(unsigned current_value)
|
||||||
_maxValue = maxValue;
|
{
|
||||||
_current_value = 0;
|
if (current_value >= m_next_threshold)
|
||||||
_intervalPercent = _maxValue / 100;
|
{
|
||||||
_nextThreshold = _intervalPercent;
|
m_next_threshold += m_percent_interval;
|
||||||
_lastPercent = 0;
|
printPercent(current_value / (double)m_max_value * 100);
|
||||||
_step = step;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** If there has been significant progress, display it. */
|
|
||||||
void printStatus(unsigned currentValue) {
|
|
||||||
if (currentValue >= _nextThreshold) {
|
|
||||||
_nextThreshold += _intervalPercent;
|
|
||||||
printPercent( currentValue / (double)_maxValue * 100 );
|
|
||||||
}
|
}
|
||||||
if (currentValue + 1 == _maxValue)
|
if (current_value + 1 == m_max_value)
|
||||||
std::cout << " 100%" << std::endl;
|
std::cout << " 100%" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void printIncrement() {
|
void printIncrement()
|
||||||
|
{
|
||||||
#pragma omp atomic
|
#pragma omp atomic
|
||||||
++_current_value;
|
++m_current_value;
|
||||||
printStatus(_current_value);
|
printStatus(m_current_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void printAddition(const unsigned addition) {
|
void printAddition(const unsigned addition)
|
||||||
|
{
|
||||||
#pragma omp atomic
|
#pragma omp atomic
|
||||||
_current_value += addition;
|
m_current_value += addition;
|
||||||
printStatus(_current_value);
|
printStatus(m_current_value);
|
||||||
}
|
}
|
||||||
private:
|
|
||||||
unsigned _current_value;
|
|
||||||
unsigned _maxValue;
|
|
||||||
unsigned _intervalPercent;
|
|
||||||
unsigned _nextThreshold;
|
|
||||||
unsigned _lastPercent;
|
|
||||||
unsigned _step;
|
|
||||||
|
|
||||||
/** Displays the new progress. */
|
private:
|
||||||
void printPercent(double percent) {
|
unsigned m_current_value;
|
||||||
while (percent >= _lastPercent+_step) {
|
unsigned m_max_value;
|
||||||
_lastPercent+=_step;
|
unsigned m_percent_interval;
|
||||||
if (_lastPercent % 10 == 0) {
|
unsigned m_next_threshold;
|
||||||
std::cout << " " << _lastPercent << "% ";
|
unsigned m_last_percent;
|
||||||
|
unsigned m_step;
|
||||||
|
|
||||||
|
// Displays progress.
|
||||||
|
void printPercent(double percent)
|
||||||
|
{
|
||||||
|
while (percent >= m_last_percent + m_step)
|
||||||
|
{
|
||||||
|
m_last_percent += m_step;
|
||||||
|
if (m_last_percent % 10 == 0)
|
||||||
|
{
|
||||||
|
std::cout << " " << m_last_percent << "% ";
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
std::cout << ".";
|
std::cout << ".";
|
||||||
}
|
}
|
||||||
std::cout.flush();
|
std::cout.flush();
|
||||||
|
@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PHANTOMNODES_H_
|
#ifndef PHANTOM_NODES_H
|
||||||
#define PHANTOMNODES_H_
|
#define PHANTOM_NODES_H
|
||||||
|
|
||||||
#include <osrm/Coordinate.h>
|
#include <osrm/Coordinate.h>
|
||||||
#include "../Util/SimpleLogger.h"
|
#include "../Util/SimpleLogger.h"
|
||||||
@ -171,4 +171,4 @@ inline std::ostream& operator<<(std::ostream &out, const PhantomNode & pn)
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* PHANTOMNODES_H_ */
|
#endif // PHANTOM_NODES_H
|
||||||
|
@ -30,34 +30,34 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#include "../typedefs.h"
|
#include "../typedefs.h"
|
||||||
|
|
||||||
struct QueryEdge {
|
struct QueryEdge
|
||||||
|
{
|
||||||
NodeID source;
|
NodeID source;
|
||||||
NodeID target;
|
NodeID target;
|
||||||
struct EdgeData {
|
struct EdgeData
|
||||||
NodeID id:31;
|
{
|
||||||
bool shortcut:1;
|
NodeID id : 31;
|
||||||
int distance:30;
|
bool shortcut : 1;
|
||||||
bool forward:1;
|
int distance : 30;
|
||||||
bool backward:1;
|
bool forward : 1;
|
||||||
|
bool backward : 1;
|
||||||
} data;
|
} data;
|
||||||
|
|
||||||
bool operator<( const QueryEdge& right ) const {
|
bool operator<(const QueryEdge &right) const
|
||||||
if ( source != right.source ) {
|
{
|
||||||
|
if (source != right.source)
|
||||||
|
{
|
||||||
return source < right.source;
|
return source < right.source;
|
||||||
}
|
}
|
||||||
return target < right.target;
|
return target < right.target;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator== ( const QueryEdge& right ) const {
|
bool operator==(const QueryEdge &right) const
|
||||||
return (
|
{
|
||||||
source == right.source &&
|
return (source == right.source && target == right.target &&
|
||||||
target == right.target &&
|
data.distance == right.data.distance && data.shortcut == right.data.shortcut &&
|
||||||
data.distance == right.data.distance &&
|
data.forward == right.data.forward && data.backward == right.data.backward &&
|
||||||
data.shortcut == right.data.shortcut &&
|
data.id == right.data.id);
|
||||||
data.forward == right.data.forward &&
|
|
||||||
data.backward == right.data.backward &&
|
|
||||||
data.id == right.data.id
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -36,52 +36,50 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
struct NodeInfo {
|
struct NodeInfo
|
||||||
typedef NodeID key_type; //type of NodeID
|
{
|
||||||
typedef int value_type; //type of lat,lons
|
typedef NodeID key_type; // type of NodeID
|
||||||
|
typedef int value_type; // type of lat,lons
|
||||||
|
|
||||||
NodeInfo(int lat, int lon, NodeID id) : lat(lat), lon(lon), id(id) { }
|
NodeInfo(int lat, int lon, NodeID id) : lat(lat), lon(lon), id(id) {}
|
||||||
NodeInfo()
|
NodeInfo()
|
||||||
:
|
: lat(std::numeric_limits<int>::max()), lon(std::numeric_limits<int>::max()),
|
||||||
lat(std::numeric_limits<int>::max()),
|
id(std::numeric_limits<unsigned>::max())
|
||||||
lon(std::numeric_limits<int>::max()),
|
{
|
||||||
id(std::numeric_limits<unsigned>::max())
|
}
|
||||||
{ }
|
|
||||||
|
|
||||||
int lat;
|
int lat;
|
||||||
int lon;
|
int lon;
|
||||||
NodeID id;
|
NodeID id;
|
||||||
|
|
||||||
static NodeInfo min_value() {
|
static NodeInfo min_value()
|
||||||
return NodeInfo(
|
{
|
||||||
-90*COORDINATE_PRECISION,
|
return NodeInfo(-90 * COORDINATE_PRECISION,
|
||||||
-180*COORDINATE_PRECISION,
|
-180 * COORDINATE_PRECISION,
|
||||||
std::numeric_limits<NodeID>::min()
|
std::numeric_limits<NodeID>::min());
|
||||||
);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static NodeInfo max_value() {
|
static NodeInfo max_value()
|
||||||
return NodeInfo(
|
{
|
||||||
90*COORDINATE_PRECISION,
|
return NodeInfo(90 * COORDINATE_PRECISION,
|
||||||
180*COORDINATE_PRECISION,
|
180 * COORDINATE_PRECISION,
|
||||||
std::numeric_limits<NodeID>::max()
|
std::numeric_limits<NodeID>::max());
|
||||||
);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
value_type operator[](const std::size_t n) const {
|
value_type operator[](const std::size_t n) const
|
||||||
switch(n) {
|
{
|
||||||
case 1:
|
switch (n)
|
||||||
return lat;
|
{
|
||||||
// break;
|
case 1:
|
||||||
case 0:
|
return lat;
|
||||||
return lon;
|
case 0:
|
||||||
// break;
|
return lon;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
BOOST_ASSERT_MSG(false, "should not happen");
|
BOOST_ASSERT_MSG(false, "should not happen");
|
||||||
return std::numeric_limits<unsigned>::max();
|
return std::numeric_limits<unsigned>::max();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //QUERY_NODE_H
|
#endif // QUERY_NODE_H
|
||||||
|
@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef RAWROUTEDATA_H_
|
#ifndef RAW_ROUTE_DATA_H
|
||||||
#define RAWROUTEDATA_H_
|
#define RAW_ROUTE_DATA_H
|
||||||
|
|
||||||
#include "../DataStructures/PhantomNodes.h"
|
#include "../DataStructures/PhantomNodes.h"
|
||||||
#include "../typedefs.h"
|
#include "../typedefs.h"
|
||||||
@ -37,53 +37,47 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
struct PathData {
|
struct PathData
|
||||||
PathData() :
|
{
|
||||||
node(UINT_MAX),
|
PathData()
|
||||||
name_id(UINT_MAX),
|
: node(std::numeric_limits<unsigned>::max()), name_id(std::numeric_limits<unsigned>::max()),
|
||||||
durationOfSegment(UINT_MAX),
|
segment_duration(std::numeric_limits<unsigned>::max()),
|
||||||
turnInstruction(UCHAR_MAX)
|
turn_instruction(std::numeric_limits<unsigned char>::max())
|
||||||
{ }
|
{
|
||||||
|
}
|
||||||
|
|
||||||
PathData(
|
PathData(NodeID no, unsigned na, unsigned tu, unsigned dur)
|
||||||
NodeID no,
|
: node(no), name_id(na), segment_duration(dur), turn_instruction(tu)
|
||||||
unsigned na,
|
{
|
||||||
unsigned tu,
|
}
|
||||||
unsigned dur
|
|
||||||
) :
|
|
||||||
node(no),
|
|
||||||
name_id(na),
|
|
||||||
durationOfSegment(dur),
|
|
||||||
turnInstruction(tu)
|
|
||||||
{ }
|
|
||||||
NodeID node;
|
NodeID node;
|
||||||
unsigned name_id;
|
unsigned name_id;
|
||||||
unsigned durationOfSegment;
|
unsigned segment_duration;
|
||||||
short turnInstruction;
|
short turn_instruction;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RawRouteData {
|
struct RawRouteData
|
||||||
std::vector< std::vector<PathData> > unpacked_path_segments;
|
{
|
||||||
std::vector< PathData > unpacked_alternative;
|
std::vector<std::vector<PathData>> unpacked_path_segments;
|
||||||
std::vector< PhantomNodes > segmentEndCoordinates;
|
std::vector<PathData> unpacked_alternative;
|
||||||
std::vector< FixedPointCoordinate > rawViaNodeCoordinates;
|
std::vector<PhantomNodes> segment_end_coordinates;
|
||||||
unsigned checkSum;
|
std::vector<FixedPointCoordinate> raw_via_node_coordinates;
|
||||||
int lengthOfShortestPath;
|
unsigned check_sum;
|
||||||
int lengthOfAlternativePath;
|
int shortest_path_length;
|
||||||
|
int alternative_path_length;
|
||||||
bool source_traversed_in_reverse;
|
bool source_traversed_in_reverse;
|
||||||
bool target_traversed_in_reverse;
|
bool target_traversed_in_reverse;
|
||||||
bool alt_source_traversed_in_reverse;
|
bool alt_source_traversed_in_reverse;
|
||||||
bool alt_target_traversed_in_reverse;
|
bool alt_target_traversed_in_reverse;
|
||||||
|
|
||||||
RawRouteData() :
|
RawRouteData()
|
||||||
checkSum(UINT_MAX),
|
: check_sum(std::numeric_limits<unsigned>::max()),
|
||||||
lengthOfShortestPath(INT_MAX),
|
shortest_path_length(std::numeric_limits<int>::max()),
|
||||||
lengthOfAlternativePath(INT_MAX),
|
alternative_path_length(std::numeric_limits<int>::max()),
|
||||||
source_traversed_in_reverse(false),
|
source_traversed_in_reverse(false), target_traversed_in_reverse(false),
|
||||||
target_traversed_in_reverse(false),
|
alt_source_traversed_in_reverse(false), alt_target_traversed_in_reverse(false)
|
||||||
alt_source_traversed_in_reverse(false),
|
{
|
||||||
alt_target_traversed_in_reverse(false)
|
}
|
||||||
{ }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* RAWROUTEDATA_H_ */
|
#endif // RAW_ROUTE_DATA_H
|
||||||
|
@ -33,7 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
RouteParameters::RouteParameters()
|
RouteParameters::RouteParameters()
|
||||||
: zoomLevel(18), printInstructions(false), alternateRoute(true), geometry(true),
|
: zoomLevel(18), printInstructions(false), alternateRoute(true), geometry(true),
|
||||||
compression(true), deprecatedAPI(false), checkSum(-1)
|
compression(true), deprecatedAPI(false), check_sum(-1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ void RouteParameters::setAlternateRouteFlag(const bool b) { alternateRoute = b;
|
|||||||
|
|
||||||
void RouteParameters::setDeprecatedAPIFlag(const std::string &) { deprecatedAPI = true; }
|
void RouteParameters::setDeprecatedAPIFlag(const std::string &) { deprecatedAPI = true; }
|
||||||
|
|
||||||
void RouteParameters::setChecksum(const unsigned c) { checkSum = c; }
|
void RouteParameters::setChecksum(const unsigned c) { check_sum = c; }
|
||||||
|
|
||||||
void RouteParameters::setInstructionFlag(const bool b) { printInstructions = b; }
|
void RouteParameters::setInstructionFlag(const bool b) { printInstructions = b; }
|
||||||
|
|
||||||
|
@ -29,40 +29,26 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#define SEARCHENGINE_H
|
#define SEARCHENGINE_H
|
||||||
|
|
||||||
#include "SearchEngineData.h"
|
#include "SearchEngineData.h"
|
||||||
#include "PhantomNodes.h"
|
|
||||||
#include "QueryEdge.h"
|
|
||||||
#include "../RoutingAlgorithms/AlternativePathRouting.h"
|
#include "../RoutingAlgorithms/AlternativePathRouting.h"
|
||||||
#include "../RoutingAlgorithms/ShortestPathRouting.h"
|
#include "../RoutingAlgorithms/ShortestPathRouting.h"
|
||||||
|
|
||||||
#include "../Util/StringUtil.h"
|
template <class DataFacadeT> class SearchEngine
|
||||||
#include "../typedefs.h"
|
{
|
||||||
|
private:
|
||||||
#include <osrm/Coordinate.h>
|
DataFacadeT *facade;
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
|
||||||
|
|
||||||
#include <climits>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
template<class DataFacadeT>
|
|
||||||
class SearchEngine {
|
|
||||||
private:
|
|
||||||
DataFacadeT * facade;
|
|
||||||
SearchEngineData engine_working_data;
|
SearchEngineData engine_working_data;
|
||||||
public:
|
|
||||||
ShortestPathRouting<DataFacadeT> shortest_path;
|
|
||||||
AlternativeRouting <DataFacadeT> alternative_path;
|
|
||||||
|
|
||||||
explicit SearchEngine( DataFacadeT * facade )
|
public:
|
||||||
:
|
ShortestPathRouting<DataFacadeT> shortest_path;
|
||||||
facade (facade),
|
AlternativeRouting<DataFacadeT> alternative_path;
|
||||||
shortest_path (facade, engine_working_data),
|
|
||||||
alternative_path (facade, engine_working_data)
|
explicit SearchEngine(DataFacadeT *facade)
|
||||||
{}
|
: facade(facade), shortest_path(facade, engine_working_data),
|
||||||
|
alternative_path(facade, engine_working_data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
~SearchEngine() {}
|
~SearchEngine() {}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SEARCHENGINE_H
|
#endif // SEARCHENGINE_H
|
||||||
|
@ -44,8 +44,6 @@ struct HeapData
|
|||||||
/* explicit */ HeapData(NodeID p) : parent(p) {}
|
/* explicit */ HeapData(NodeID p) : parent(p) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// typedef StaticGraph<QueryEdge::EdgeData> QueryGraph;
|
|
||||||
|
|
||||||
struct SearchEngineData
|
struct SearchEngineData
|
||||||
{
|
{
|
||||||
typedef BinaryHeap<NodeID, NodeID, int, HeapData, UnorderedMapStorage<NodeID, int>> QueryHeap;
|
typedef BinaryHeap<NodeID, NodeID, int, HeapData, UnorderedMapStorage<NodeID, int>> QueryHeap;
|
||||||
|
@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SEGMENTINFORMATION_H_
|
#ifndef SEGMENT_INFORMATION_H
|
||||||
#define SEGMENTINFORMATION_H_
|
#define SEGMENT_INFORMATION_H
|
||||||
|
|
||||||
#include "TurnInstructions.h"
|
#include "TurnInstructions.h"
|
||||||
|
|
||||||
@ -35,47 +35,36 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <osrm/Coordinate.h>
|
#include <osrm/Coordinate.h>
|
||||||
|
|
||||||
// Struct fits everything in one cache line
|
// Struct fits everything in one cache line
|
||||||
struct SegmentInformation {
|
struct SegmentInformation
|
||||||
|
{
|
||||||
FixedPointCoordinate location;
|
FixedPointCoordinate location;
|
||||||
NodeID name_id;
|
NodeID name_id;
|
||||||
unsigned duration;
|
unsigned duration;
|
||||||
double length;
|
double length;
|
||||||
short bearing; //more than enough [0..3600] fits into 12 bits
|
short bearing; // more than enough [0..3600] fits into 12 bits
|
||||||
TurnInstruction turn_instruction;
|
TurnInstruction turn_instruction;
|
||||||
bool necessary;
|
bool necessary;
|
||||||
|
|
||||||
explicit SegmentInformation(
|
explicit SegmentInformation(const FixedPointCoordinate &location,
|
||||||
const FixedPointCoordinate & location,
|
const NodeID name_id,
|
||||||
const NodeID name_id,
|
const unsigned duration,
|
||||||
const unsigned duration,
|
const double length,
|
||||||
const double length,
|
const TurnInstruction turn_instruction,
|
||||||
const TurnInstruction turn_instruction,
|
const bool necessary)
|
||||||
const bool necessary
|
: location(location), name_id(name_id), duration(duration), length(length), bearing(0),
|
||||||
) :
|
turn_instruction(turn_instruction), necessary(necessary)
|
||||||
location(location),
|
{
|
||||||
name_id(name_id),
|
}
|
||||||
duration(duration),
|
|
||||||
length(length),
|
|
||||||
bearing(0),
|
|
||||||
turn_instruction(turn_instruction),
|
|
||||||
necessary(necessary)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
explicit SegmentInformation(
|
explicit SegmentInformation(const FixedPointCoordinate &location,
|
||||||
const FixedPointCoordinate & location,
|
const NodeID name_id,
|
||||||
const NodeID name_id,
|
const unsigned duration,
|
||||||
const unsigned duration,
|
const double length,
|
||||||
const double length,
|
const TurnInstruction turn_instruction)
|
||||||
const TurnInstruction turn_instruction
|
: location(location), name_id(name_id), duration(duration), length(length), bearing(0),
|
||||||
) :
|
turn_instruction(turn_instruction), necessary(turn_instruction != 0)
|
||||||
location(location),
|
{
|
||||||
name_id(name_id),
|
}
|
||||||
duration(duration),
|
|
||||||
length(length),
|
|
||||||
bearing(0),
|
|
||||||
turn_instruction(turn_instruction),
|
|
||||||
necessary(turn_instruction != 0)
|
|
||||||
{ }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* SEGMENTINFORMATION_H_ */
|
#endif /* SEGMENT_INFORMATION_H */
|
||||||
|
@ -31,7 +31,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "../Util/OSRMException.h"
|
#include "../Util/OSRMException.h"
|
||||||
#include "../Util/SimpleLogger.h"
|
#include "../Util/SimpleLogger.h"
|
||||||
|
|
||||||
#include <boost/noncopyable.hpp>
|
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include <boost/filesystem/fstream.hpp>
|
#include <boost/filesystem/fstream.hpp>
|
||||||
#include <boost/interprocess/mapped_region.hpp>
|
#include <boost/interprocess/mapped_region.hpp>
|
||||||
@ -42,207 +41,191 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <sys/shm.h>
|
#include <sys/shm.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <cstring>
|
// #include <cstring>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
|
||||||
struct OSRMLockFile {
|
struct OSRMLockFile
|
||||||
boost::filesystem::path operator()() {
|
{
|
||||||
boost::filesystem::path temp_dir =
|
boost::filesystem::path operator()()
|
||||||
boost::filesystem::temp_directory_path();
|
{
|
||||||
boost::filesystem::path lock_file = temp_dir / "osrm.lock";
|
boost::filesystem::path temp_dir = boost::filesystem::temp_directory_path();
|
||||||
return lock_file;
|
boost::filesystem::path lock_file = temp_dir / "osrm.lock";
|
||||||
}
|
return lock_file;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class SharedMemory : boost::noncopyable {
|
class SharedMemory
|
||||||
|
{
|
||||||
|
|
||||||
//Remove shared memory on destruction
|
// Remove shared memory on destruction
|
||||||
class shm_remove : boost::noncopyable {
|
class shm_remove
|
||||||
private:
|
{
|
||||||
int m_shmid;
|
private:
|
||||||
bool m_initialized;
|
int m_shmid;
|
||||||
public:
|
bool m_initialized;
|
||||||
void SetID(int shmid) {
|
|
||||||
m_shmid = shmid;
|
|
||||||
m_initialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
shm_remove() : m_shmid(INT_MIN), m_initialized(false) {}
|
public:
|
||||||
|
void SetID(int shmid)
|
||||||
|
{
|
||||||
|
m_shmid = shmid;
|
||||||
|
m_initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
~shm_remove(){
|
shm_remove() : m_shmid(INT_MIN), m_initialized(false) {}
|
||||||
if(m_initialized) {
|
shm_remove(const shm_remove &) = delete;
|
||||||
SimpleLogger().Write(logDEBUG) <<
|
~shm_remove()
|
||||||
"automatic memory deallocation";
|
{
|
||||||
if(!boost::interprocess::xsi_shared_memory::remove(m_shmid)) {
|
if (m_initialized)
|
||||||
SimpleLogger().Write(logDEBUG) << "could not deallocate id " << m_shmid;
|
{
|
||||||
}
|
SimpleLogger().Write(logDEBUG) << "automatic memory deallocation";
|
||||||
}
|
if (!boost::interprocess::xsi_shared_memory::remove(m_shmid))
|
||||||
}
|
{
|
||||||
};
|
SimpleLogger().Write(logDEBUG) << "could not deallocate id " << m_shmid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void * Ptr() const {
|
void *Ptr() const { return region.get_address(); }
|
||||||
return region.get_address();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename IdentifierT >
|
SharedMemory() = delete;
|
||||||
SharedMemory(
|
SharedMemory(const SharedMemory &) = delete;
|
||||||
const boost::filesystem::path & lock_file,
|
|
||||||
const IdentifierT id,
|
|
||||||
const uint64_t size = 0,
|
|
||||||
bool read_write = false,
|
|
||||||
bool remove_prev = true
|
|
||||||
) : key(
|
|
||||||
lock_file.string().c_str(),
|
|
||||||
id
|
|
||||||
) {
|
|
||||||
if( 0 == size ){ //read_only
|
|
||||||
shm = boost::interprocess::xsi_shared_memory (
|
|
||||||
boost::interprocess::open_only,
|
|
||||||
key
|
|
||||||
);
|
|
||||||
|
|
||||||
region = boost::interprocess::mapped_region (
|
template <typename IdentifierT>
|
||||||
shm,
|
SharedMemory(const boost::filesystem::path &lock_file,
|
||||||
(
|
const IdentifierT id,
|
||||||
read_write ?
|
const uint64_t size = 0,
|
||||||
boost::interprocess::read_write :
|
bool read_write = false,
|
||||||
boost::interprocess::read_only
|
bool remove_prev = true)
|
||||||
)
|
: key(lock_file.string().c_str(), id)
|
||||||
);
|
{
|
||||||
} else { //writeable pointer
|
if (0 == size)
|
||||||
//remove previously allocated mem
|
{ // read_only
|
||||||
if( remove_prev ) {
|
shm = boost::interprocess::xsi_shared_memory(boost::interprocess::open_only, key);
|
||||||
Remove(key);
|
|
||||||
}
|
region = boost::interprocess::mapped_region(
|
||||||
shm = boost::interprocess::xsi_shared_memory (
|
shm,
|
||||||
boost::interprocess::open_or_create,
|
(read_write ? boost::interprocess::read_write : boost::interprocess::read_only));
|
||||||
key,
|
}
|
||||||
size
|
else
|
||||||
);
|
{ // writeable pointer
|
||||||
|
// remove previously allocated mem
|
||||||
|
if (remove_prev)
|
||||||
|
{
|
||||||
|
Remove(key);
|
||||||
|
}
|
||||||
|
shm = boost::interprocess::xsi_shared_memory(
|
||||||
|
boost::interprocess::open_or_create, key, size);
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
if( -1 == shmctl(shm.get_shmid(), SHM_LOCK, 0) ) {
|
if (-1 == shmctl(shm.get_shmid(), SHM_LOCK, 0))
|
||||||
if( ENOMEM == errno ) {
|
{
|
||||||
SimpleLogger().Write(logWARNING) <<
|
if (ENOMEM == errno)
|
||||||
"could not lock shared memory to RAM";
|
{
|
||||||
}
|
SimpleLogger().Write(logWARNING) << "could not lock shared memory to RAM";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
region = boost::interprocess::mapped_region (
|
region = boost::interprocess::mapped_region(shm, boost::interprocess::read_write);
|
||||||
shm,
|
|
||||||
boost::interprocess::read_write
|
|
||||||
);
|
|
||||||
|
|
||||||
remover.SetID( shm.get_shmid() );
|
remover.SetID(shm.get_shmid());
|
||||||
SimpleLogger().Write(logDEBUG) <<
|
SimpleLogger().Write(logDEBUG) << "writeable memory allocated " << size << " bytes";
|
||||||
"writeable memory allocated " << size << " bytes";
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
template<typename IdentifierT >
|
template <typename IdentifierT> static bool RegionExists(const IdentifierT id)
|
||||||
static bool RegionExists(
|
{
|
||||||
const IdentifierT id
|
bool result = true;
|
||||||
) {
|
try
|
||||||
bool result = true;
|
{
|
||||||
try {
|
OSRMLockFile lock_file;
|
||||||
OSRMLockFile lock_file;
|
boost::interprocess::xsi_key key(lock_file().string().c_str(), id);
|
||||||
boost::interprocess::xsi_key key( lock_file().string().c_str(), id );
|
result = RegionExists(key);
|
||||||
result = RegionExists(key);
|
}
|
||||||
} catch(...) {
|
catch (...) { result = false; }
|
||||||
result = false;
|
return result;
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename IdentifierT >
|
template <typename IdentifierT> static bool Remove(const IdentifierT id)
|
||||||
static bool Remove(
|
{
|
||||||
const IdentifierT id
|
OSRMLockFile lock_file;
|
||||||
) {
|
boost::interprocess::xsi_key key(lock_file().string().c_str(), id);
|
||||||
OSRMLockFile lock_file;
|
return Remove(key);
|
||||||
boost::interprocess::xsi_key key( lock_file().string().c_str(), id );
|
}
|
||||||
return Remove(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool RegionExists( const boost::interprocess::xsi_key &key ) {
|
static bool RegionExists(const boost::interprocess::xsi_key &key)
|
||||||
bool result = true;
|
{
|
||||||
try {
|
bool result = true;
|
||||||
boost::interprocess::xsi_shared_memory shm(
|
try { boost::interprocess::xsi_shared_memory shm(boost::interprocess::open_only, key); }
|
||||||
boost::interprocess::open_only,
|
catch (...) { result = false; }
|
||||||
key
|
return result;
|
||||||
);
|
}
|
||||||
} catch(...) {
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool Remove(
|
static bool Remove(const boost::interprocess::xsi_key &key)
|
||||||
const boost::interprocess::xsi_key &key
|
{
|
||||||
) {
|
bool ret = false;
|
||||||
bool ret = false;
|
try
|
||||||
try{
|
{
|
||||||
SimpleLogger().Write(logDEBUG) << "deallocating prev memory";
|
SimpleLogger().Write(logDEBUG) << "deallocating prev memory";
|
||||||
boost::interprocess::xsi_shared_memory xsi(
|
boost::interprocess::xsi_shared_memory xsi(boost::interprocess::open_only, key);
|
||||||
boost::interprocess::open_only,
|
ret = boost::interprocess::xsi_shared_memory::remove(xsi.get_shmid());
|
||||||
key
|
}
|
||||||
);
|
catch (const boost::interprocess::interprocess_exception &e)
|
||||||
ret = boost::interprocess::xsi_shared_memory::remove(xsi.get_shmid());
|
{
|
||||||
} catch(const boost::interprocess::interprocess_exception &e){
|
if (e.get_error_code() != boost::interprocess::not_found_error)
|
||||||
if(e.get_error_code() != boost::interprocess::not_found_error) {
|
{
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::interprocess::xsi_key key;
|
boost::interprocess::xsi_key key;
|
||||||
boost::interprocess::xsi_shared_memory shm;
|
boost::interprocess::xsi_shared_memory shm;
|
||||||
boost::interprocess::mapped_region region;
|
boost::interprocess::mapped_region region;
|
||||||
shm_remove remover;
|
shm_remove remover;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class LockFileT = OSRMLockFile>
|
template <class LockFileT = OSRMLockFile> class SharedMemoryFactory_tmpl
|
||||||
class SharedMemoryFactory_tmpl : boost::noncopyable {
|
{
|
||||||
public:
|
public:
|
||||||
|
template <typename IdentifierT>
|
||||||
|
static SharedMemory *Get(const IdentifierT &id,
|
||||||
|
const uint64_t size = 0,
|
||||||
|
bool read_write = false,
|
||||||
|
bool remove_prev = true)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
LockFileT lock_file;
|
||||||
|
if (!boost::filesystem::exists(lock_file()))
|
||||||
|
{
|
||||||
|
if (0 == size)
|
||||||
|
{
|
||||||
|
throw OSRMException("lock file does not exist, exiting");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
boost::filesystem::ofstream ofs(lock_file());
|
||||||
|
ofs.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new SharedMemory(lock_file(), id, size, read_write, remove_prev);
|
||||||
|
}
|
||||||
|
catch (const boost::interprocess::interprocess_exception &e)
|
||||||
|
{
|
||||||
|
SimpleLogger().Write(logWARNING) << "caught exception: " << e.what() << ", code "
|
||||||
|
<< e.get_error_code();
|
||||||
|
throw OSRMException(e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template<typename IdentifierT >
|
SharedMemoryFactory_tmpl() = delete;
|
||||||
static SharedMemory * Get(
|
SharedMemoryFactory_tmpl(const SharedMemoryFactory_tmpl &) = delete;
|
||||||
const IdentifierT & id,
|
|
||||||
const uint64_t size = 0,
|
|
||||||
bool read_write = false,
|
|
||||||
bool remove_prev = true
|
|
||||||
) {
|
|
||||||
try {
|
|
||||||
LockFileT lock_file;
|
|
||||||
if(!boost::filesystem::exists(lock_file()) ) {
|
|
||||||
if( 0 == size ) {
|
|
||||||
throw OSRMException("lock file does not exist, exiting");
|
|
||||||
} else {
|
|
||||||
boost::filesystem::ofstream ofs(lock_file());
|
|
||||||
ofs.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new SharedMemory(
|
|
||||||
lock_file(),
|
|
||||||
id,
|
|
||||||
size,
|
|
||||||
read_write,
|
|
||||||
remove_prev
|
|
||||||
);
|
|
||||||
} catch(const boost::interprocess::interprocess_exception &e){
|
|
||||||
SimpleLogger().Write(logWARNING) <<
|
|
||||||
"caught exception: " << e.what() <<
|
|
||||||
", code " << e.get_error_code();
|
|
||||||
throw OSRMException(e.what());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
SharedMemoryFactory_tmpl() {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef SharedMemoryFactory_tmpl<> SharedMemoryFactory;
|
typedef SharedMemoryFactory_tmpl<> SharedMemoryFactory;
|
||||||
|
@ -31,153 +31,114 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "../Util/SimpleLogger.h"
|
#include "../Util/SimpleLogger.h"
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
#include <boost/type_traits.hpp>
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
#include <type_traits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
template<typename DataT>
|
template <typename DataT> class ShMemIterator : public std::iterator<std::input_iterator_tag, DataT>
|
||||||
class ShMemIterator : public std::iterator<std::input_iterator_tag, DataT> {
|
{
|
||||||
DataT * p;
|
DataT *p;
|
||||||
public:
|
|
||||||
explicit ShMemIterator(DataT * x) : p(x) {}
|
public:
|
||||||
ShMemIterator(const ShMemIterator & mit) : p(mit.p) {}
|
explicit ShMemIterator(DataT *x) : p(x) {}
|
||||||
ShMemIterator& operator++() {
|
ShMemIterator(const ShMemIterator &mit) : p(mit.p) {}
|
||||||
|
ShMemIterator &operator++()
|
||||||
|
{
|
||||||
++p;
|
++p;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
ShMemIterator operator++(int) {
|
ShMemIterator operator++(int)
|
||||||
|
{
|
||||||
ShMemIterator tmp(*this);
|
ShMemIterator tmp(*this);
|
||||||
operator++();
|
operator++();
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
ShMemIterator operator+(std::ptrdiff_t diff) {
|
ShMemIterator operator+(std::ptrdiff_t diff)
|
||||||
ShMemIterator tmp(p+diff);
|
{
|
||||||
|
ShMemIterator tmp(p + diff);
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
bool operator==(const ShMemIterator& rhs) {
|
bool operator==(const ShMemIterator &rhs) { return p == rhs.p; }
|
||||||
return p==rhs.p;
|
bool operator!=(const ShMemIterator &rhs) { return p != rhs.p; }
|
||||||
}
|
DataT &operator*() { return *p; }
|
||||||
bool operator!=(const ShMemIterator& rhs) {
|
|
||||||
return p!=rhs.p;
|
|
||||||
}
|
|
||||||
DataT& operator*() {
|
|
||||||
return *p;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename DataT>
|
template <typename DataT> class SharedMemoryWrapper
|
||||||
class SharedMemoryWrapper {
|
{
|
||||||
private:
|
private:
|
||||||
DataT * m_ptr;
|
DataT *m_ptr;
|
||||||
std::size_t m_size;
|
std::size_t m_size;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SharedMemoryWrapper() :
|
SharedMemoryWrapper() : m_ptr(nullptr), m_size(0) {}
|
||||||
m_ptr(NULL),
|
|
||||||
m_size(0)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
SharedMemoryWrapper(DataT * ptr, std::size_t size) :
|
SharedMemoryWrapper(DataT *ptr, std::size_t size) : m_ptr(ptr), m_size(size) {}
|
||||||
m_ptr(ptr),
|
|
||||||
m_size(size)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
void swap( SharedMemoryWrapper<DataT> & other ) {
|
void swap(SharedMemoryWrapper<DataT> &other)
|
||||||
|
{
|
||||||
BOOST_ASSERT_MSG(m_size != 0 || other.size() != 0, "size invalid");
|
BOOST_ASSERT_MSG(m_size != 0 || other.size() != 0, "size invalid");
|
||||||
std::swap( m_size, other.m_size);
|
std::swap(m_size, other.m_size);
|
||||||
std::swap( m_ptr , other.m_ptr );
|
std::swap(m_ptr, other.m_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// void SetData(const DataT * ptr, const std::size_t size) {
|
DataT &at(const std::size_t index) { return m_ptr[index]; }
|
||||||
// BOOST_ASSERT_MSG( 0 == m_size, "vector not empty");
|
|
||||||
// BOOST_ASSERT_MSG( 0 < size , "new vector empty");
|
|
||||||
// m_ptr.reset(ptr);
|
|
||||||
// m_size = size;
|
|
||||||
// }
|
|
||||||
|
|
||||||
DataT & at(const std::size_t index) {
|
const DataT &at(const std::size_t index) const { return m_ptr[index]; }
|
||||||
return m_ptr[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
const DataT & at(const std::size_t index) const {
|
ShMemIterator<DataT> begin() const { return ShMemIterator<DataT>(m_ptr); }
|
||||||
return m_ptr[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
ShMemIterator<DataT> begin() const {
|
ShMemIterator<DataT> end() const { return ShMemIterator<DataT>(m_ptr + m_size); }
|
||||||
return ShMemIterator<DataT>(m_ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
ShMemIterator<DataT> end() const {
|
|
||||||
return ShMemIterator<DataT>(m_ptr+m_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t size() const { return m_size; }
|
std::size_t size() const { return m_size; }
|
||||||
|
|
||||||
bool empty() const { return 0 == size(); }
|
bool empty() const { return 0 == size(); }
|
||||||
|
|
||||||
DataT & operator[](const unsigned index) {
|
DataT &operator[](const unsigned index)
|
||||||
|
{
|
||||||
BOOST_ASSERT_MSG(index < m_size, "invalid size");
|
BOOST_ASSERT_MSG(index < m_size, "invalid size");
|
||||||
return m_ptr[index];
|
return m_ptr[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
const DataT & operator[](const unsigned index) const {
|
const DataT &operator[](const unsigned index) const
|
||||||
|
{
|
||||||
BOOST_ASSERT_MSG(index < m_size, "invalid size");
|
BOOST_ASSERT_MSG(index < m_size, "invalid size");
|
||||||
return m_ptr[index];
|
return m_ptr[index];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template <> class SharedMemoryWrapper<bool>
|
||||||
class SharedMemoryWrapper<bool> {
|
{
|
||||||
private:
|
private:
|
||||||
unsigned * m_ptr;
|
unsigned *m_ptr;
|
||||||
std::size_t m_size;
|
std::size_t m_size;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SharedMemoryWrapper() :
|
SharedMemoryWrapper() : m_ptr(nullptr), m_size(0) {}
|
||||||
m_ptr(NULL),
|
|
||||||
m_size(0)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
SharedMemoryWrapper(unsigned * ptr, std::size_t size) :
|
SharedMemoryWrapper(unsigned *ptr, std::size_t size) : m_ptr(ptr), m_size(size) {}
|
||||||
m_ptr(ptr),
|
|
||||||
m_size(size)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
void swap( SharedMemoryWrapper<bool> & other ) {
|
void swap(SharedMemoryWrapper<bool> &other)
|
||||||
|
{
|
||||||
BOOST_ASSERT_MSG(m_size != 0 || other.size() != 0, "size invalid");
|
BOOST_ASSERT_MSG(m_size != 0 || other.size() != 0, "size invalid");
|
||||||
std::swap( m_size, other.m_size);
|
std::swap(m_size, other.m_size);
|
||||||
std::swap( m_ptr , other.m_ptr );
|
std::swap(m_ptr, other.m_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// void SetData(const DataT * ptr, const std::size_t size) {
|
bool at(const std::size_t index) const
|
||||||
// BOOST_ASSERT_MSG( 0 == m_size, "vector not empty");
|
{
|
||||||
// BOOST_ASSERT_MSG( 0 < size , "new vector empty");
|
|
||||||
// m_ptr.reset(ptr);
|
|
||||||
// m_size = size;
|
|
||||||
// }
|
|
||||||
|
|
||||||
bool at(const std::size_t index) const {
|
|
||||||
// BOOST_ASSERT_MSG(index < m_size, "invalid size");
|
|
||||||
const unsigned bucket = index / 32;
|
const unsigned bucket = index / 32;
|
||||||
const unsigned offset = index % 32;
|
const unsigned offset = index % 32;
|
||||||
return m_ptr[bucket] & (1 << offset);
|
return m_ptr[bucket] & (1 << offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ShMemIterator<DataT> begin() const {
|
|
||||||
// return ShMemIterator<DataT>(m_ptr);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// ShMemIterator<DataT> end() const {
|
|
||||||
// return ShMemIterator<DataT>(m_ptr+m_size);
|
|
||||||
// }
|
|
||||||
|
|
||||||
std::size_t size() const { return m_size; }
|
std::size_t size() const { return m_size; }
|
||||||
|
|
||||||
bool empty() const { return 0 == size(); }
|
bool empty() const { return 0 == size(); }
|
||||||
|
|
||||||
bool operator[](const unsigned index) {
|
bool operator[](const unsigned index)
|
||||||
|
{
|
||||||
BOOST_ASSERT_MSG(index < m_size, "invalid size");
|
BOOST_ASSERT_MSG(index < m_size, "invalid size");
|
||||||
const unsigned bucket = index / 32;
|
const unsigned bucket = index / 32;
|
||||||
const unsigned offset = index % 32;
|
const unsigned offset = index % 32;
|
||||||
@ -185,13 +146,11 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename DataT, bool UseSharedMemory>
|
template <typename DataT, bool UseSharedMemory> struct ShM
|
||||||
struct ShM {
|
{
|
||||||
typedef typename boost::conditional<
|
typedef typename std::conditional<UseSharedMemory,
|
||||||
UseSharedMemory,
|
SharedMemoryWrapper<DataT>,
|
||||||
SharedMemoryWrapper<DataT>,
|
std::vector<DataT>>::type vector;
|
||||||
std::vector<DataT>
|
};
|
||||||
>::type vector;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif //SHARED_MEMORY_VECTOR_WRAPPER_H
|
#endif // SHARED_MEMORY_VECTOR_WRAPPER_H
|
||||||
|
@ -36,17 +36,20 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <stack>
|
#include <stack>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
namespace KDTree {
|
namespace KDTree
|
||||||
|
{
|
||||||
|
|
||||||
#define KDTREE_BASESIZE (8)
|
#define KDTREE_BASESIZE (8)
|
||||||
|
|
||||||
template< unsigned k, typename T >
|
template <unsigned k, typename T> class BoundingBox
|
||||||
class BoundingBox {
|
{
|
||||||
public:
|
public:
|
||||||
BoundingBox() {
|
BoundingBox()
|
||||||
for ( unsigned dim = 0; dim < k; ++dim ) {
|
{
|
||||||
min[dim] = std::numeric_limits< T >::min();
|
for (unsigned dim = 0; dim < k; ++dim)
|
||||||
max[dim] = std::numeric_limits< T >::max();
|
{
|
||||||
|
min[dim] = std::numeric_limits<T>::min();
|
||||||
|
max[dim] = std::numeric_limits<T>::max();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,102 +57,118 @@ public:
|
|||||||
T max[k];
|
T max[k];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NoData {};
|
struct NoData
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
template< unsigned k, typename T >
|
template <unsigned k, typename T> class EuclidianMetric
|
||||||
class EuclidianMetric {
|
{
|
||||||
public:
|
public:
|
||||||
double operator() ( const T left[k], const T right[k] ) {
|
double operator()(const T left[k], const T right[k])
|
||||||
|
{
|
||||||
double result = 0;
|
double result = 0;
|
||||||
for ( unsigned i = 0; i < k; ++i ) {
|
for (unsigned i = 0; i < k; ++i)
|
||||||
|
{
|
||||||
double temp = (double)left[i] - (double)right[i];
|
double temp = (double)left[i] - (double)right[i];
|
||||||
result += temp * temp;
|
result += temp * temp;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
double operator() ( const BoundingBox< k, T > &box, const T point[k] ) {
|
double operator()(const BoundingBox<k, T> &box, const T point[k])
|
||||||
|
{
|
||||||
T nearest[k];
|
T nearest[k];
|
||||||
for ( unsigned dim = 0; dim < k; ++dim ) {
|
for (unsigned dim = 0; dim < k; ++dim)
|
||||||
if ( point[dim] < box.min[dim] )
|
{
|
||||||
|
if (point[dim] < box.min[dim])
|
||||||
nearest[dim] = box.min[dim];
|
nearest[dim] = box.min[dim];
|
||||||
else if ( point[dim] > box.max[dim] )
|
else if (point[dim] > box.max[dim])
|
||||||
nearest[dim] = box.max[dim];
|
nearest[dim] = box.max[dim];
|
||||||
else
|
else
|
||||||
nearest[dim] = point[dim];
|
nearest[dim] = point[dim];
|
||||||
}
|
}
|
||||||
return operator() ( point, nearest );
|
return operator()(point, nearest);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template < unsigned k, typename T, typename Data = NoData, typename Metric = EuclidianMetric< k, T > >
|
template <unsigned k, typename T, typename Data = NoData, typename Metric = EuclidianMetric<k, T>>
|
||||||
class StaticKDTree {
|
class StaticKDTree
|
||||||
public:
|
{
|
||||||
|
public:
|
||||||
struct InputPoint {
|
struct InputPoint
|
||||||
|
{
|
||||||
T coordinates[k];
|
T coordinates[k];
|
||||||
Data data;
|
Data data;
|
||||||
bool operator==( const InputPoint& right )
|
bool operator==(const InputPoint &right)
|
||||||
{
|
{
|
||||||
for ( int i = 0; i < k; i++ ) {
|
for (int i = 0; i < k; i++)
|
||||||
if ( coordinates[i] != right.coordinates[i] )
|
{
|
||||||
|
if (coordinates[i] != right.coordinates[i])
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit StaticKDTree( std::vector< InputPoint > * points ){
|
explicit StaticKDTree(std::vector<InputPoint> *points)
|
||||||
BOOST_ASSERT( k > 0 );
|
{
|
||||||
BOOST_ASSERT ( points->size() > 0 );
|
BOOST_ASSERT(k > 0);
|
||||||
|
BOOST_ASSERT(points->size() > 0);
|
||||||
size = points->size();
|
size = points->size();
|
||||||
kdtree = new InputPoint[size];
|
kdtree = new InputPoint[size];
|
||||||
for ( Iterator i = 0; i != size; ++i ) {
|
for (Iterator i = 0; i != size; ++i)
|
||||||
|
{
|
||||||
kdtree[i] = points->at(i);
|
kdtree[i] = points->at(i);
|
||||||
for ( unsigned dim = 0; dim < k; ++dim ) {
|
for (unsigned dim = 0; dim < k; ++dim)
|
||||||
if ( kdtree[i].coordinates[dim] < boundingBox.min[dim] )
|
{
|
||||||
|
if (kdtree[i].coordinates[dim] < boundingBox.min[dim])
|
||||||
boundingBox.min[dim] = kdtree[i].coordinates[dim];
|
boundingBox.min[dim] = kdtree[i].coordinates[dim];
|
||||||
if ( kdtree[i].coordinates[dim] > boundingBox.max[dim] )
|
if (kdtree[i].coordinates[dim] > boundingBox.max[dim])
|
||||||
boundingBox.max[dim] = kdtree[i].coordinates[dim];
|
boundingBox.max[dim] = kdtree[i].coordinates[dim];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::stack< Tree > s;
|
std::stack<Tree> s;
|
||||||
s.push ( Tree ( 0, size, 0 ) );
|
s.push(Tree(0, size, 0));
|
||||||
while ( !s.empty() ) {
|
while (!s.empty())
|
||||||
|
{
|
||||||
Tree tree = s.top();
|
Tree tree = s.top();
|
||||||
s.pop();
|
s.pop();
|
||||||
|
|
||||||
if ( tree.right - tree.left < KDTREE_BASESIZE )
|
if (tree.right - tree.left < KDTREE_BASESIZE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Iterator middle = tree.left + ( tree.right - tree.left ) / 2;
|
Iterator middle = tree.left + (tree.right - tree.left) / 2;
|
||||||
std::nth_element( kdtree + tree.left, kdtree + middle, kdtree + tree.right, Less( tree.dimension ) );
|
std::nth_element(
|
||||||
s.push( Tree( tree.left, middle, ( tree.dimension + 1 ) % k ) );
|
kdtree + tree.left, kdtree + middle, kdtree + tree.right, Less(tree.dimension));
|
||||||
s.push( Tree( middle + 1, tree.right, ( tree.dimension + 1 ) % k ) );
|
s.push(Tree(tree.left, middle, (tree.dimension + 1) % k));
|
||||||
|
s.push(Tree(middle + 1, tree.right, (tree.dimension + 1) % k));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~StaticKDTree(){
|
~StaticKDTree() { delete[] kdtree; }
|
||||||
delete[] kdtree;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NearestNeighbor( InputPoint* result, const InputPoint& point ) {
|
bool NearestNeighbor(InputPoint *result, const InputPoint &point)
|
||||||
|
{
|
||||||
Metric distance;
|
Metric distance;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
double nearestDistance = std::numeric_limits< T >::max();
|
double nearestDistance = std::numeric_limits<T>::max();
|
||||||
std::stack< NNTree > s;
|
std::stack<NNTree> s;
|
||||||
s.push ( NNTree ( 0, size, 0, boundingBox ) );
|
s.push(NNTree(0, size, 0, boundingBox));
|
||||||
while ( !s.empty() ) {
|
while (!s.empty())
|
||||||
|
{
|
||||||
NNTree tree = s.top();
|
NNTree tree = s.top();
|
||||||
s.pop();
|
s.pop();
|
||||||
|
|
||||||
if ( distance( tree.box, point.coordinates ) >= nearestDistance )
|
if (distance(tree.box, point.coordinates) >= nearestDistance)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ( tree.right - tree.left < KDTREE_BASESIZE ) {
|
if (tree.right - tree.left < KDTREE_BASESIZE)
|
||||||
for ( unsigned i = tree.left; i < tree.right; i++ ) {
|
{
|
||||||
double newDistance = distance( kdtree[i].coordinates, point.coordinates );
|
for (unsigned i = tree.left; i < tree.right; i++)
|
||||||
if ( newDistance < nearestDistance ) {
|
{
|
||||||
|
double newDistance = distance(kdtree[i].coordinates, point.coordinates);
|
||||||
|
if (newDistance < nearestDistance)
|
||||||
|
{
|
||||||
nearestDistance = newDistance;
|
nearestDistance = newDistance;
|
||||||
*result = kdtree[i];
|
*result = kdtree[i];
|
||||||
found = true;
|
found = true;
|
||||||
@ -158,73 +177,84 @@ public:
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterator middle = tree.left + ( tree.right - tree.left ) / 2;
|
Iterator middle = tree.left + (tree.right - tree.left) / 2;
|
||||||
|
|
||||||
double newDistance = distance( kdtree[middle].coordinates, point.coordinates );
|
double newDistance = distance(kdtree[middle].coordinates, point.coordinates);
|
||||||
if ( newDistance < nearestDistance ) {
|
if (newDistance < nearestDistance)
|
||||||
|
{
|
||||||
nearestDistance = newDistance;
|
nearestDistance = newDistance;
|
||||||
*result = kdtree[middle];
|
*result = kdtree[middle];
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Less comperator( tree.dimension );
|
Less comperator(tree.dimension);
|
||||||
if ( !comperator( point, kdtree[middle] ) ) {
|
if (!comperator(point, kdtree[middle]))
|
||||||
NNTree first( middle + 1, tree.right, ( tree.dimension + 1 ) % k, tree.box );
|
{
|
||||||
NNTree second( tree.left, middle, ( tree.dimension + 1 ) % k, tree.box );
|
NNTree first(middle + 1, tree.right, (tree.dimension + 1) % k, tree.box);
|
||||||
|
NNTree second(tree.left, middle, (tree.dimension + 1) % k, tree.box);
|
||||||
first.box.min[tree.dimension] = kdtree[middle].coordinates[tree.dimension];
|
first.box.min[tree.dimension] = kdtree[middle].coordinates[tree.dimension];
|
||||||
second.box.max[tree.dimension] = kdtree[middle].coordinates[tree.dimension];
|
second.box.max[tree.dimension] = kdtree[middle].coordinates[tree.dimension];
|
||||||
s.push( second );
|
s.push(second);
|
||||||
s.push( first );
|
s.push(first);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
NNTree first( middle + 1, tree.right, ( tree.dimension + 1 ) % k, tree.box );
|
{
|
||||||
NNTree second( tree.left, middle, ( tree.dimension + 1 ) % k, tree.box );
|
NNTree first(middle + 1, tree.right, (tree.dimension + 1) % k, tree.box);
|
||||||
|
NNTree second(tree.left, middle, (tree.dimension + 1) % k, tree.box);
|
||||||
first.box.min[tree.dimension] = kdtree[middle].coordinates[tree.dimension];
|
first.box.min[tree.dimension] = kdtree[middle].coordinates[tree.dimension];
|
||||||
second.box.max[tree.dimension] = kdtree[middle].coordinates[tree.dimension];
|
second.box.max[tree.dimension] = kdtree[middle].coordinates[tree.dimension];
|
||||||
s.push( first );
|
s.push(first);
|
||||||
s.push( second );
|
s.push(second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef unsigned Iterator;
|
typedef unsigned Iterator;
|
||||||
struct Tree {
|
struct Tree
|
||||||
|
{
|
||||||
Iterator left;
|
Iterator left;
|
||||||
Iterator right;
|
Iterator right;
|
||||||
unsigned dimension;
|
unsigned dimension;
|
||||||
Tree() {}
|
Tree() {}
|
||||||
Tree( Iterator l, Iterator r, unsigned d ): left( l ), right( r ), dimension( d ) {}
|
Tree(Iterator l, Iterator r, unsigned d) : left(l), right(r), dimension(d) {}
|
||||||
};
|
};
|
||||||
struct NNTree {
|
struct NNTree
|
||||||
|
{
|
||||||
Iterator left;
|
Iterator left;
|
||||||
Iterator right;
|
Iterator right;
|
||||||
unsigned dimension;
|
unsigned dimension;
|
||||||
BoundingBox< k, T > box;
|
BoundingBox<k, T> box;
|
||||||
NNTree() {}
|
NNTree() {}
|
||||||
NNTree( Iterator l, Iterator r, unsigned d, const BoundingBox< k, T >& b ): left( l ), right( r ), dimension( d ), box ( b ) {}
|
NNTree(Iterator l, Iterator r, unsigned d, const BoundingBox<k, T> &b)
|
||||||
|
: left(l), right(r), dimension(d), box(b)
|
||||||
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
class Less {
|
class Less
|
||||||
public:
|
{
|
||||||
explicit Less( unsigned d ) {
|
public:
|
||||||
|
explicit Less(unsigned d)
|
||||||
|
{
|
||||||
dimension = d;
|
dimension = d;
|
||||||
BOOST_ASSERT( dimension < k );
|
BOOST_ASSERT(dimension < k);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator() ( const InputPoint& left, const InputPoint& right ) {
|
bool operator()(const InputPoint &left, const InputPoint &right)
|
||||||
BOOST_ASSERT( dimension < k );
|
{
|
||||||
|
BOOST_ASSERT(dimension < k);
|
||||||
return left.coordinates[dimension] < right.coordinates[dimension];
|
return left.coordinates[dimension] < right.coordinates[dimension];
|
||||||
}
|
}
|
||||||
private:
|
|
||||||
|
private:
|
||||||
unsigned dimension;
|
unsigned dimension;
|
||||||
};
|
};
|
||||||
|
|
||||||
BoundingBox< k, T > boundingBox;
|
BoundingBox<k, T> boundingBox;
|
||||||
InputPoint* kdtree;
|
InputPoint *kdtree;
|
||||||
Iterator size;
|
Iterator size;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // STATICKDTREE_H_INCLUDED
|
#endif // STATICKDTREE_H_INCLUDED
|
||||||
|
@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef STATICRTREE_H_
|
#ifndef STATICRTREE_H
|
||||||
#define STATICRTREE_H_
|
#define STATICRTREE_H
|
||||||
|
|
||||||
#include "DeallocatingVector.h"
|
#include "DeallocatingVector.h"
|
||||||
#include "HilbertValue.h"
|
#include "HilbertValue.h"
|
||||||
@ -45,7 +45,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include <boost/filesystem/fstream.hpp>
|
#include <boost/filesystem/fstream.hpp>
|
||||||
#include <boost/noncopyable.hpp>
|
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <boost/thread.hpp>
|
#include <boost/thread.hpp>
|
||||||
|
|
||||||
@ -67,7 +66,7 @@ static boost::thread_specific_ptr<boost::filesystem::ifstream> thread_local_rtre
|
|||||||
template <class DataT,
|
template <class DataT,
|
||||||
class CoordinateListT = std::vector<FixedPointCoordinate>,
|
class CoordinateListT = std::vector<FixedPointCoordinate>,
|
||||||
bool UseSharedMemory = false>
|
bool UseSharedMemory = false>
|
||||||
class StaticRTree : boost::noncopyable
|
class StaticRTree
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct RectangleInt2D
|
struct RectangleInt2D
|
||||||
@ -269,6 +268,9 @@ class StaticRTree : boost::noncopyable
|
|||||||
boost::shared_ptr<CoordinateListT> m_coordinate_list;
|
boost::shared_ptr<CoordinateListT> m_coordinate_list;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
StaticRTree() = delete;
|
||||||
|
StaticRTree(const StaticRTree &) = delete;
|
||||||
|
|
||||||
// Construct a packed Hilbert-R-Tree with Kamel-Faloutsos algorithm [1]
|
// Construct a packed Hilbert-R-Tree with Kamel-Faloutsos algorithm [1]
|
||||||
explicit StaticRTree(std::vector<DataT> &input_data_vector,
|
explicit StaticRTree(std::vector<DataT> &input_data_vector,
|
||||||
const std::string tree_node_filename,
|
const std::string tree_node_filename,
|
||||||
@ -524,7 +526,7 @@ class StaticRTree : boost::noncopyable
|
|||||||
for (uint32_t i = 0; i < current_leaf_node.object_count; ++i)
|
for (uint32_t i = 0; i < current_leaf_node.object_count; ++i)
|
||||||
{
|
{
|
||||||
DataT const ¤t_edge = current_leaf_node.objects[i];
|
DataT const ¤t_edge = current_leaf_node.objects[i];
|
||||||
if (ignore_tiny_components && current_edge.belongsToTinyComponent)
|
if (ignore_tiny_components && current_edge.is_in_tiny_cc)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -637,7 +639,7 @@ class StaticRTree : boost::noncopyable
|
|||||||
for (uint32_t i = 0; i < current_leaf_node.object_count; ++i)
|
for (uint32_t i = 0; i < current_leaf_node.object_count; ++i)
|
||||||
{
|
{
|
||||||
DataT ¤t_edge = current_leaf_node.objects[i];
|
DataT ¤t_edge = current_leaf_node.objects[i];
|
||||||
if (ignore_tiny_components && current_edge.belongsToTinyComponent)
|
if (ignore_tiny_components && current_edge.is_in_tiny_cc)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -784,4 +786,4 @@ class StaticRTree : boost::noncopyable
|
|||||||
//[1] "On Packing R-Trees"; I. Kamel, C. Faloutsos; 1993; DOI: 10.1145/170088.170403
|
//[1] "On Packing R-Trees"; I. Kamel, C. Faloutsos; 1993; DOI: 10.1145/170088.170403
|
||||||
//[2] "Nearest Neighbor Queries", N. Roussopulos et al; 1995; DOI: 10.1145/223784.223794
|
//[2] "Nearest Neighbor Queries", N. Roussopulos et al; 1995; DOI: 10.1145/223784.223794
|
||||||
|
|
||||||
#endif /* STATICRTREE_H_ */
|
#endif // STATICRTREE_H
|
||||||
|
@ -25,18 +25,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TURNINSTRUCTIONS_H_
|
#ifndef TURN_INSTRUCTIONS_H
|
||||||
#define TURNINSTRUCTIONS_H_
|
#define TURN_INSTRUCTIONS_H
|
||||||
|
|
||||||
#include <boost/noncopyable.hpp>
|
|
||||||
|
|
||||||
typedef unsigned char TurnInstruction;
|
typedef unsigned char TurnInstruction;
|
||||||
|
|
||||||
//This is a hack until c++0x is available enough to use scoped enums
|
// This is a hack until c++0x is available enough to use scoped enums
|
||||||
struct TurnInstructionsClass : boost::noncopyable {
|
struct TurnInstructionsClass
|
||||||
|
{
|
||||||
|
TurnInstructionsClass() = delete;
|
||||||
|
TurnInstructionsClass(const TurnInstructionsClass&) = delete;
|
||||||
|
|
||||||
const static TurnInstruction NoTurn = 0; //Give no instruction at all
|
const static TurnInstruction NoTurn = 0; // Give no instruction at all
|
||||||
const static TurnInstruction GoStraight = 1; //Tell user to go straight!
|
const static TurnInstruction GoStraight = 1; // Tell user to go straight!
|
||||||
const static TurnInstruction TurnSlightRight = 2;
|
const static TurnInstruction TurnSlightRight = 2;
|
||||||
const static TurnInstruction TurnRight = 3;
|
const static TurnInstruction TurnRight = 3;
|
||||||
const static TurnInstruction TurnSharpRight = 4;
|
const static TurnInstruction TurnSharpRight = 4;
|
||||||
@ -55,41 +56,51 @@ struct TurnInstructionsClass : boost::noncopyable {
|
|||||||
const static TurnInstruction LeaveAgainstAllowedDirection = 17;
|
const static TurnInstruction LeaveAgainstAllowedDirection = 17;
|
||||||
|
|
||||||
const static TurnInstruction AccessRestrictionFlag = 128;
|
const static TurnInstruction AccessRestrictionFlag = 128;
|
||||||
const static TurnInstruction InverseAccessRestrictionFlag = 0x7f; // ~128 does not work without a warning.
|
const static TurnInstruction InverseAccessRestrictionFlag =
|
||||||
|
0x7f; // ~128 does not work without a warning.
|
||||||
|
|
||||||
const static int AccessRestrictionPenalty = 1 << 15; //unrelated to the bit set in the restriction flag
|
const static int AccessRestrictionPenalty =
|
||||||
|
1 << 15; // unrelated to the bit set in the restriction flag
|
||||||
|
|
||||||
static inline TurnInstruction GetTurnDirectionOfInstruction( const double angle ) {
|
static inline TurnInstruction GetTurnDirectionOfInstruction(const double angle)
|
||||||
if(angle >= 23 && angle < 67) {
|
{
|
||||||
|
if (angle >= 23 && angle < 67)
|
||||||
|
{
|
||||||
return TurnSharpRight;
|
return TurnSharpRight;
|
||||||
}
|
}
|
||||||
if (angle >= 67 && angle < 113) {
|
if (angle >= 67 && angle < 113)
|
||||||
|
{
|
||||||
return TurnRight;
|
return TurnRight;
|
||||||
}
|
}
|
||||||
if (angle >= 113 && angle < 158) {
|
if (angle >= 113 && angle < 158)
|
||||||
|
{
|
||||||
return TurnSlightRight;
|
return TurnSlightRight;
|
||||||
}
|
}
|
||||||
if (angle >= 158 && angle < 202) {
|
if (angle >= 158 && angle < 202)
|
||||||
|
{
|
||||||
return GoStraight;
|
return GoStraight;
|
||||||
}
|
}
|
||||||
if (angle >= 202 && angle < 248) {
|
if (angle >= 202 && angle < 248)
|
||||||
|
{
|
||||||
return TurnSlightLeft;
|
return TurnSlightLeft;
|
||||||
}
|
}
|
||||||
if (angle >= 248 && angle < 292) {
|
if (angle >= 248 && angle < 292)
|
||||||
|
{
|
||||||
return TurnLeft;
|
return TurnLeft;
|
||||||
}
|
}
|
||||||
if (angle >= 292 && angle < 336) {
|
if (angle >= 292 && angle < 336)
|
||||||
|
{
|
||||||
return TurnSharpLeft;
|
return TurnSharpLeft;
|
||||||
}
|
}
|
||||||
return UTurn;
|
return UTurn;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool TurnIsNecessary ( const short turnInstruction ) {
|
static inline bool TurnIsNecessary(const short turnInstruction)
|
||||||
if(NoTurn == turnInstruction || StayOnRoundAbout == turnInstruction)
|
{
|
||||||
|
if (NoTurn == turnInstruction || StayOnRoundAbout == turnInstruction)
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* TURNINSTRUCTIONS_H_ */
|
#endif /* TURN_INSTRUCTIONS_H */
|
||||||
|
@ -25,14 +25,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef FASTXORHASH_H_
|
#ifndef XOR_FAST_HASH_H
|
||||||
#define FASTXORHASH_H_
|
#define XOR_FAST_HASH_H
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This is an implementation of Tabulation hashing, which has suprising properties like universality.
|
This is an implementation of Tabulation hashing, which has suprising properties like
|
||||||
|
universality.
|
||||||
The space requirement is 2*2^16 = 256 kb of memory, which fits into L2 cache.
|
The space requirement is 2*2^16 = 256 kb of memory, which fits into L2 cache.
|
||||||
Evaluation boils down to 10 or less assembly instruction on any recent X86 CPU:
|
Evaluation boils down to 10 or less assembly instruction on any recent X86 CPU:
|
||||||
|
|
||||||
@ -48,49 +49,61 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
10: ret
|
10: ret
|
||||||
|
|
||||||
*/
|
*/
|
||||||
class XORFastHash { //65k entries
|
class XORFastHash
|
||||||
|
{ // 65k entries
|
||||||
std::vector<unsigned short> table1;
|
std::vector<unsigned short> table1;
|
||||||
std::vector<unsigned short> table2;
|
std::vector<unsigned short> table2;
|
||||||
public:
|
|
||||||
XORFastHash() {
|
public:
|
||||||
|
XORFastHash()
|
||||||
|
{
|
||||||
table1.resize(2 << 16);
|
table1.resize(2 << 16);
|
||||||
table2.resize(2 << 16);
|
table2.resize(2 << 16);
|
||||||
for(unsigned i = 0; i < (2 << 16); ++i) {
|
for (unsigned i = 0; i < (2 << 16); ++i)
|
||||||
table1[i] = i; table2[i] = i;
|
{
|
||||||
|
table1[i] = i;
|
||||||
|
table2[i] = i;
|
||||||
}
|
}
|
||||||
std::random_shuffle(table1.begin(), table1.end());
|
std::random_shuffle(table1.begin(), table1.end());
|
||||||
std::random_shuffle(table2.begin(), table2.end());
|
std::random_shuffle(table2.begin(), table2.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned short operator()(const unsigned originalValue) const {
|
inline unsigned short operator()(const unsigned originalValue) const
|
||||||
|
{
|
||||||
unsigned short lsb = ((originalValue) & 0xffff);
|
unsigned short lsb = ((originalValue) & 0xffff);
|
||||||
unsigned short msb = (((originalValue) >> 16) & 0xffff);
|
unsigned short msb = (((originalValue) >> 16) & 0xffff);
|
||||||
return table1[lsb] ^ table2[msb];
|
return table1[lsb] ^ table2[msb];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class XORMiniHash { //256 entries
|
class XORMiniHash
|
||||||
|
{ // 256 entries
|
||||||
std::vector<unsigned char> table1;
|
std::vector<unsigned char> table1;
|
||||||
std::vector<unsigned char> table2;
|
std::vector<unsigned char> table2;
|
||||||
std::vector<unsigned char> table3;
|
std::vector<unsigned char> table3;
|
||||||
std::vector<unsigned char> table4;
|
std::vector<unsigned char> table4;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
XORMiniHash() {
|
XORMiniHash()
|
||||||
|
{
|
||||||
table1.resize(1 << 8);
|
table1.resize(1 << 8);
|
||||||
table2.resize(1 << 8);
|
table2.resize(1 << 8);
|
||||||
table3.resize(1 << 8);
|
table3.resize(1 << 8);
|
||||||
table4.resize(1 << 8);
|
table4.resize(1 << 8);
|
||||||
for(unsigned i = 0; i < (1 << 8); ++i) {
|
for (unsigned i = 0; i < (1 << 8); ++i)
|
||||||
table1[i] = i; table2[i] = i;
|
{
|
||||||
table3[i] = i; table4[i] = i;
|
table1[i] = i;
|
||||||
|
table2[i] = i;
|
||||||
|
table3[i] = i;
|
||||||
|
table4[i] = i;
|
||||||
}
|
}
|
||||||
std::random_shuffle(table1.begin(), table1.end());
|
std::random_shuffle(table1.begin(), table1.end());
|
||||||
std::random_shuffle(table2.begin(), table2.end());
|
std::random_shuffle(table2.begin(), table2.end());
|
||||||
std::random_shuffle(table3.begin(), table3.end());
|
std::random_shuffle(table3.begin(), table3.end());
|
||||||
std::random_shuffle(table4.begin(), table4.end());
|
std::random_shuffle(table4.begin(), table4.end());
|
||||||
}
|
}
|
||||||
unsigned char operator()(const unsigned originalValue) const {
|
unsigned char operator()(const unsigned originalValue) const
|
||||||
|
{
|
||||||
unsigned char byte1 = ((originalValue) & 0xff);
|
unsigned char byte1 = ((originalValue) & 0xff);
|
||||||
unsigned char byte2 = ((originalValue >> 8) & 0xff);
|
unsigned char byte2 = ((originalValue >> 8) & 0xff);
|
||||||
unsigned char byte3 = ((originalValue >> 16) & 0xff);
|
unsigned char byte3 = ((originalValue >> 16) & 0xff);
|
||||||
@ -99,4 +112,4 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FASTXORHASH_H_ */
|
#endif // XOR_FAST_HASH_H
|
||||||
|
@ -25,63 +25,65 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef XORFASTHASHSTORAGE_H_
|
#ifndef XOR_FAST_HASH_STORAGE_H
|
||||||
#define XORFASTHASHSTORAGE_H_
|
#define XOR_FAST_HASH_STORAGE_H
|
||||||
|
|
||||||
#include "XORFastHash.h"
|
#include "XORFastHash.h"
|
||||||
|
|
||||||
#include <climits>
|
#include <limits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <bitset>
|
|
||||||
|
|
||||||
template< typename NodeID, typename Key >
|
template <typename NodeID, typename Key> class XORFastHashStorage
|
||||||
class XORFastHashStorage {
|
{
|
||||||
public:
|
public:
|
||||||
struct HashCell{
|
struct HashCell
|
||||||
|
{
|
||||||
Key key;
|
Key key;
|
||||||
NodeID id;
|
NodeID id;
|
||||||
unsigned time;
|
unsigned time;
|
||||||
HashCell() : key(UINT_MAX), id(UINT_MAX), time(UINT_MAX) {}
|
HashCell()
|
||||||
|
: key(std::numeric_limits<unsigned>::max()), id(std::numeric_limits<unsigned>::max()),
|
||||||
HashCell(const HashCell & other) : key(other.key), id(other.id), time(other.time) { }
|
time(std::numeric_limits<unsigned>::max())
|
||||||
|
{
|
||||||
inline operator Key() const {
|
|
||||||
return key;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void operator=(const Key & keyToInsert) {
|
HashCell(const HashCell &other) : key(other.key), id(other.id), time(other.time) {}
|
||||||
key = keyToInsert;
|
|
||||||
}
|
inline operator Key() const { return key; }
|
||||||
|
|
||||||
|
inline void operator=(const Key &key_to_insert) { key = key_to_insert; }
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit XORFastHashStorage( size_t ) : positions(2<<16), currentTimestamp(0) { }
|
explicit XORFastHashStorage(size_t) : positions(2 << 16), current_timestamp(0) {}
|
||||||
|
|
||||||
inline HashCell& operator[]( const NodeID node ) {
|
inline HashCell &operator[](const NodeID node)
|
||||||
unsigned short position = fastHash(node);
|
{
|
||||||
while((positions[position].time == currentTimestamp) && (positions[position].id != node)){
|
unsigned short position = fast_hasher(node);
|
||||||
++position %= (2<<16);
|
while ((positions[position].time == current_timestamp) && (positions[position].id != node))
|
||||||
|
{
|
||||||
|
++position %= (2 << 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
positions[position].id = node;
|
positions[position].id = node;
|
||||||
positions[position].time = currentTimestamp;
|
positions[position].time = current_timestamp;
|
||||||
return positions[position];
|
return positions[position];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Clear() {
|
inline void Clear()
|
||||||
++currentTimestamp;
|
{
|
||||||
if(UINT_MAX == currentTimestamp) {
|
++current_timestamp;
|
||||||
|
if (std::numeric_limits<unsigned>::max() == current_timestamp)
|
||||||
|
{
|
||||||
positions.clear();
|
positions.clear();
|
||||||
positions.resize((2<<16));
|
positions.resize((2 << 16));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
XORFastHashStorage() : positions(2<<16), currentTimestamp(0) {}
|
XORFastHashStorage() : positions(2 << 16), current_timestamp(0) {}
|
||||||
std::vector<HashCell> positions;
|
std::vector<HashCell> positions;
|
||||||
XORFastHash fastHash;
|
XORFastHash fast_hasher;
|
||||||
unsigned currentTimestamp;
|
unsigned current_timestamp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif // XOR_FAST_HASH_STORAGE_H
|
||||||
#endif /* XORFASTHASHSTORAGE_H_ */
|
|
||||||
|
|
||||||
|
@ -90,9 +90,9 @@ void DescriptionFactory::AppendSegment(const FixedPointCoordinate &coordinate,
|
|||||||
{
|
{
|
||||||
path_description.push_back(SegmentInformation(coordinate,
|
path_description.push_back(SegmentInformation(coordinate,
|
||||||
path_point.name_id,
|
path_point.name_id,
|
||||||
path_point.durationOfSegment,
|
path_point.segment_duration,
|
||||||
0,
|
0,
|
||||||
path_point.turnInstruction));
|
path_point.turn_instruction));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ template <class DataFacadeT> class GPXDescriptor : public BaseDescriptor<DataFac
|
|||||||
" OpenStreetMap contributors (ODbL)</license></copyright>"
|
" OpenStreetMap contributors (ODbL)</license></copyright>"
|
||||||
"</metadata>");
|
"</metadata>");
|
||||||
reply.content.push_back("<rte>");
|
reply.content.push_back("<rte>");
|
||||||
bool found_route = (raw_route.lengthOfShortestPath != INVALID_EDGE_WEIGHT) &&
|
bool found_route = (raw_route.shortest_path_length != INVALID_EDGE_WEIGHT) &&
|
||||||
(!raw_route.unpacked_path_segments.front().empty());
|
(!raw_route.unpacked_path_segments.front().empty());
|
||||||
if (found_route)
|
if (found_route)
|
||||||
{
|
{
|
||||||
|
@ -110,7 +110,7 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
|
|||||||
facade = f;
|
facade = f;
|
||||||
reply.content.push_back("{\"status\":");
|
reply.content.push_back("{\"status\":");
|
||||||
|
|
||||||
if (INVALID_EDGE_WEIGHT == raw_route.lengthOfShortestPath)
|
if (INVALID_EDGE_WEIGHT == raw_route.shortest_path_length)
|
||||||
{
|
{
|
||||||
// We do not need to do much, if there is no route ;-)
|
// We do not need to do much, if there is no route ;-)
|
||||||
reply.content.push_back(
|
reply.content.push_back(
|
||||||
@ -118,14 +118,14 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleLogger().Write(logDEBUG) << "distance: " << raw_route.lengthOfShortestPath;
|
SimpleLogger().Write(logDEBUG) << "distance: " << raw_route.shortest_path_length;
|
||||||
|
|
||||||
// check if first segment is non-zero
|
// check if first segment is non-zero
|
||||||
std::string road_name =
|
std::string road_name =
|
||||||
facade->GetEscapedNameForNameID(phantom_nodes.source_phantom.name_id);
|
facade->GetEscapedNameForNameID(phantom_nodes.source_phantom.name_id);
|
||||||
|
|
||||||
BOOST_ASSERT(raw_route.unpacked_path_segments.size() ==
|
BOOST_ASSERT(raw_route.unpacked_path_segments.size() ==
|
||||||
raw_route.segmentEndCoordinates.size());
|
raw_route.segment_end_coordinates.size());
|
||||||
|
|
||||||
description_factory.SetStartSegment(phantom_nodes.source_phantom,
|
description_factory.SetStartSegment(phantom_nodes.source_phantom,
|
||||||
raw_route.source_traversed_in_reverse);
|
raw_route.source_traversed_in_reverse);
|
||||||
@ -136,7 +136,7 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
|
|||||||
for (unsigned i = 0; i < raw_route.unpacked_path_segments.size(); ++i)
|
for (unsigned i = 0; i < raw_route.unpacked_path_segments.size(); ++i)
|
||||||
{
|
{
|
||||||
const int added_segments = DescribeLeg(raw_route.unpacked_path_segments[i],
|
const int added_segments = DescribeLeg(raw_route.unpacked_path_segments[i],
|
||||||
raw_route.segmentEndCoordinates[i]);
|
raw_route.segment_end_coordinates[i]);
|
||||||
BOOST_ASSERT(0 < added_segments);
|
BOOST_ASSERT(0 < added_segments);
|
||||||
shortest_leg_end_indices.push_back(added_segments + shortest_leg_end_indices.back());
|
shortest_leg_end_indices.push_back(added_segments + shortest_leg_end_indices.back());
|
||||||
}
|
}
|
||||||
@ -159,13 +159,13 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
|
|||||||
{
|
{
|
||||||
BuildTextualDescription(description_factory,
|
BuildTextualDescription(description_factory,
|
||||||
reply,
|
reply,
|
||||||
raw_route.lengthOfShortestPath,
|
raw_route.shortest_path_length,
|
||||||
facade,
|
facade,
|
||||||
shortest_path_segments);
|
shortest_path_segments);
|
||||||
}
|
}
|
||||||
reply.content.push_back("],");
|
reply.content.push_back("],");
|
||||||
description_factory.BuildRouteSummary(description_factory.entireLength,
|
description_factory.BuildRouteSummary(description_factory.entireLength,
|
||||||
raw_route.lengthOfShortestPath);
|
raw_route.shortest_path_length);
|
||||||
|
|
||||||
reply.content.push_back("\"route_summary\":");
|
reply.content.push_back("\"route_summary\":");
|
||||||
reply.content.push_back("{");
|
reply.content.push_back("{");
|
||||||
@ -187,7 +187,7 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
|
|||||||
reply.content.push_back(",");
|
reply.content.push_back(",");
|
||||||
|
|
||||||
// only one alternative route is computed at this time, so this is hardcoded
|
// only one alternative route is computed at this time, so this is hardcoded
|
||||||
if (raw_route.lengthOfAlternativePath != INVALID_EDGE_WEIGHT)
|
if (raw_route.alternative_path_length != INVALID_EDGE_WEIGHT)
|
||||||
{
|
{
|
||||||
alternate_descriptionFactory.SetStartSegment(phantom_nodes.source_phantom,
|
alternate_descriptionFactory.SetStartSegment(phantom_nodes.source_phantom,
|
||||||
raw_route.alt_source_traversed_in_reverse);
|
raw_route.alt_source_traversed_in_reverse);
|
||||||
@ -204,7 +204,7 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
|
|||||||
|
|
||||||
// //give an array of alternative routes
|
// //give an array of alternative routes
|
||||||
reply.content.push_back("\"alternative_geometries\": [");
|
reply.content.push_back("\"alternative_geometries\": [");
|
||||||
if (config.geometry && INVALID_EDGE_WEIGHT != raw_route.lengthOfAlternativePath)
|
if (config.geometry && INVALID_EDGE_WEIGHT != raw_route.alternative_path_length)
|
||||||
{
|
{
|
||||||
// Generate the linestrings for each alternative
|
// Generate the linestrings for each alternative
|
||||||
alternate_descriptionFactory.AppendEncodedPolylineString(config.encode_geometry,
|
alternate_descriptionFactory.AppendEncodedPolylineString(config.encode_geometry,
|
||||||
@ -212,7 +212,7 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
|
|||||||
}
|
}
|
||||||
reply.content.push_back("],");
|
reply.content.push_back("],");
|
||||||
reply.content.push_back("\"alternative_instructions\":[");
|
reply.content.push_back("\"alternative_instructions\":[");
|
||||||
if (INVALID_EDGE_WEIGHT != raw_route.lengthOfAlternativePath)
|
if (INVALID_EDGE_WEIGHT != raw_route.alternative_path_length)
|
||||||
{
|
{
|
||||||
reply.content.push_back("[");
|
reply.content.push_back("[");
|
||||||
// Generate instructions for each alternative
|
// Generate instructions for each alternative
|
||||||
@ -220,7 +220,7 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
|
|||||||
{
|
{
|
||||||
BuildTextualDescription(alternate_descriptionFactory,
|
BuildTextualDescription(alternate_descriptionFactory,
|
||||||
reply,
|
reply,
|
||||||
raw_route.lengthOfAlternativePath,
|
raw_route.alternative_path_length,
|
||||||
facade,
|
facade,
|
||||||
alternative_path_segments);
|
alternative_path_segments);
|
||||||
}
|
}
|
||||||
@ -228,11 +228,11 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
|
|||||||
}
|
}
|
||||||
reply.content.push_back("],");
|
reply.content.push_back("],");
|
||||||
reply.content.push_back("\"alternative_summaries\":[");
|
reply.content.push_back("\"alternative_summaries\":[");
|
||||||
if (INVALID_EDGE_WEIGHT != raw_route.lengthOfAlternativePath)
|
if (INVALID_EDGE_WEIGHT != raw_route.alternative_path_length)
|
||||||
{
|
{
|
||||||
// Generate route summary (length, duration) for each alternative
|
// Generate route summary (length, duration) for each alternative
|
||||||
alternate_descriptionFactory.BuildRouteSummary(
|
alternate_descriptionFactory.BuildRouteSummary(
|
||||||
alternate_descriptionFactory.entireLength, raw_route.lengthOfAlternativePath);
|
alternate_descriptionFactory.entireLength, raw_route.alternative_path_length);
|
||||||
reply.content.push_back("{");
|
reply.content.push_back("{");
|
||||||
reply.content.push_back("\"total_distance\":");
|
reply.content.push_back("\"total_distance\":");
|
||||||
reply.content.push_back(alternate_descriptionFactory.summary.lengthString);
|
reply.content.push_back(alternate_descriptionFactory.summary.lengthString);
|
||||||
@ -271,16 +271,16 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
|
|||||||
// list all viapoints so that the client may display it
|
// list all viapoints so that the client may display it
|
||||||
reply.content.push_back("\"via_points\":[");
|
reply.content.push_back("\"via_points\":[");
|
||||||
|
|
||||||
BOOST_ASSERT(!raw_route.segmentEndCoordinates.empty());
|
BOOST_ASSERT(!raw_route.segment_end_coordinates.empty());
|
||||||
|
|
||||||
std::string tmp;
|
std::string tmp;
|
||||||
FixedPointCoordinate::convertInternalReversedCoordinateToString(
|
FixedPointCoordinate::convertInternalReversedCoordinateToString(
|
||||||
raw_route.segmentEndCoordinates.front().source_phantom.location, tmp);
|
raw_route.segment_end_coordinates.front().source_phantom.location, tmp);
|
||||||
reply.content.push_back("[");
|
reply.content.push_back("[");
|
||||||
reply.content.push_back(tmp);
|
reply.content.push_back(tmp);
|
||||||
reply.content.push_back("]");
|
reply.content.push_back("]");
|
||||||
|
|
||||||
for (const PhantomNodes &nodes : raw_route.segmentEndCoordinates)
|
for (const PhantomNodes &nodes : raw_route.segment_end_coordinates)
|
||||||
{
|
{
|
||||||
tmp.clear();
|
tmp.clear();
|
||||||
FixedPointCoordinate::convertInternalReversedCoordinateToString(
|
FixedPointCoordinate::convertInternalReversedCoordinateToString(
|
||||||
@ -303,7 +303,7 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
reply.content.push_back("],\"alternative_indices\":[");
|
reply.content.push_back("],\"alternative_indices\":[");
|
||||||
if (INVALID_EDGE_WEIGHT != raw_route.lengthOfAlternativePath)
|
if (INVALID_EDGE_WEIGHT != raw_route.alternative_path_length)
|
||||||
{
|
{
|
||||||
reply.content.push_back("0,");
|
reply.content.push_back("0,");
|
||||||
tmp.clear();
|
tmp.clear();
|
||||||
@ -314,19 +314,19 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
|
|||||||
reply.content.push_back("],");
|
reply.content.push_back("],");
|
||||||
reply.content.push_back("\"hint_data\": {");
|
reply.content.push_back("\"hint_data\": {");
|
||||||
reply.content.push_back("\"checksum\":");
|
reply.content.push_back("\"checksum\":");
|
||||||
intToString(raw_route.checkSum, tmp);
|
intToString(raw_route.check_sum, tmp);
|
||||||
reply.content.push_back(tmp);
|
reply.content.push_back(tmp);
|
||||||
reply.content.push_back(", \"locations\": [");
|
reply.content.push_back(", \"locations\": [");
|
||||||
|
|
||||||
std::string hint;
|
std::string hint;
|
||||||
for (unsigned i = 0; i < raw_route.segmentEndCoordinates.size(); ++i)
|
for (unsigned i = 0; i < raw_route.segment_end_coordinates.size(); ++i)
|
||||||
{
|
{
|
||||||
reply.content.push_back("\"");
|
reply.content.push_back("\"");
|
||||||
EncodeObjectToBase64(raw_route.segmentEndCoordinates[i].source_phantom, hint);
|
EncodeObjectToBase64(raw_route.segment_end_coordinates[i].source_phantom, hint);
|
||||||
reply.content.push_back(hint);
|
reply.content.push_back(hint);
|
||||||
reply.content.push_back("\", ");
|
reply.content.push_back("\", ");
|
||||||
}
|
}
|
||||||
EncodeObjectToBase64(raw_route.segmentEndCoordinates.back().target_phantom, hint);
|
EncodeObjectToBase64(raw_route.segment_end_coordinates.back().target_phantom, hint);
|
||||||
reply.content.push_back("\"");
|
reply.content.push_back("\"");
|
||||||
reply.content.push_back(hint);
|
reply.content.push_back(hint);
|
||||||
reply.content.push_back("\"]");
|
reply.content.push_back("\"]");
|
||||||
|
@ -71,7 +71,7 @@ struct RouteParameters
|
|||||||
bool geometry;
|
bool geometry;
|
||||||
bool compression;
|
bool compression;
|
||||||
bool deprecatedAPI;
|
bool deprecatedAPI;
|
||||||
unsigned checkSum;
|
unsigned check_sum;
|
||||||
std::string service;
|
std::string service;
|
||||||
std::string outputFormat;
|
std::string outputFormat;
|
||||||
std::string jsonpParameter;
|
std::string jsonpParameter;
|
||||||
|
@ -53,7 +53,7 @@ class HelloWorldPlugin : public BasePlugin
|
|||||||
intToString(routeParameters.zoomLevel, temp_string);
|
intToString(routeParameters.zoomLevel, temp_string);
|
||||||
reply.content.push_back(temp_string);
|
reply.content.push_back(temp_string);
|
||||||
reply.content.push_back("\nchecksum: ");
|
reply.content.push_back("\nchecksum: ");
|
||||||
intToString(routeParameters.checkSum, temp_string);
|
intToString(routeParameters.check_sum, temp_string);
|
||||||
reply.content.push_back(temp_string);
|
reply.content.push_back(temp_string);
|
||||||
reply.content.push_back("\ninstructions: ");
|
reply.content.push_back("\ninstructions: ");
|
||||||
reply.content.push_back((routeParameters.printInstructions ? "yes" : "no"));
|
reply.content.push_back((routeParameters.printInstructions ? "yes" : "no"));
|
||||||
|
@ -76,7 +76,7 @@ template <class DataFacadeT> class ViaRoutePlugin : public BasePlugin
|
|||||||
}
|
}
|
||||||
|
|
||||||
RawRouteData raw_route;
|
RawRouteData raw_route;
|
||||||
raw_route.checkSum = facade->GetCheckSum();
|
raw_route.check_sum = facade->GetCheckSum();
|
||||||
|
|
||||||
if (std::any_of(begin(routeParameters.coordinates),
|
if (std::any_of(begin(routeParameters.coordinates),
|
||||||
end(routeParameters.coordinates),
|
end(routeParameters.coordinates),
|
||||||
@ -89,13 +89,13 @@ template <class DataFacadeT> class ViaRoutePlugin : public BasePlugin
|
|||||||
|
|
||||||
for (const FixedPointCoordinate &coordinate : routeParameters.coordinates)
|
for (const FixedPointCoordinate &coordinate : routeParameters.coordinates)
|
||||||
{
|
{
|
||||||
raw_route.rawViaNodeCoordinates.emplace_back(coordinate);
|
raw_route.raw_via_node_coordinates.emplace_back(coordinate);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<PhantomNode> phantom_node_vector(raw_route.rawViaNodeCoordinates.size());
|
std::vector<PhantomNode> phantom_node_vector(raw_route.raw_via_node_coordinates.size());
|
||||||
const bool checksum_OK = (routeParameters.checkSum == raw_route.checkSum);
|
const bool checksum_OK = (routeParameters.check_sum == raw_route.check_sum);
|
||||||
|
|
||||||
for (unsigned i = 0; i < raw_route.rawViaNodeCoordinates.size(); ++i)
|
for (unsigned i = 0; i < raw_route.raw_via_node_coordinates.size(); ++i)
|
||||||
{
|
{
|
||||||
if (checksum_OK && i < routeParameters.hints.size() &&
|
if (checksum_OK && i < routeParameters.hints.size() &&
|
||||||
!routeParameters.hints[i].empty())
|
!routeParameters.hints[i].empty())
|
||||||
@ -106,7 +106,7 @@ template <class DataFacadeT> class ViaRoutePlugin : public BasePlugin
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
facade->FindPhantomNodeForCoordinate(raw_route.rawViaNodeCoordinates[i],
|
facade->FindPhantomNodeForCoordinate(raw_route.raw_via_node_coordinates[i],
|
||||||
phantom_node_vector[i],
|
phantom_node_vector[i],
|
||||||
routeParameters.zoomLevel);
|
routeParameters.zoomLevel);
|
||||||
}
|
}
|
||||||
@ -116,19 +116,19 @@ template <class DataFacadeT> class ViaRoutePlugin : public BasePlugin
|
|||||||
{
|
{
|
||||||
current_phantom_node_pair.source_phantom = phantom_node_vector[i];
|
current_phantom_node_pair.source_phantom = phantom_node_vector[i];
|
||||||
current_phantom_node_pair.target_phantom = phantom_node_vector[i + 1];
|
current_phantom_node_pair.target_phantom = phantom_node_vector[i + 1];
|
||||||
raw_route.segmentEndCoordinates.emplace_back(current_phantom_node_pair);
|
raw_route.segment_end_coordinates.emplace_back(current_phantom_node_pair);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((routeParameters.alternateRoute) && (1 == raw_route.segmentEndCoordinates.size()))
|
if ((routeParameters.alternateRoute) && (1 == raw_route.segment_end_coordinates.size()))
|
||||||
{
|
{
|
||||||
search_engine_ptr->alternative_path(raw_route.segmentEndCoordinates.front(), raw_route);
|
search_engine_ptr->alternative_path(raw_route.segment_end_coordinates.front(), raw_route);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
search_engine_ptr->shortest_path(raw_route.segmentEndCoordinates, raw_route);
|
search_engine_ptr->shortest_path(raw_route.segment_end_coordinates, raw_route);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (INVALID_EDGE_WEIGHT == raw_route.lengthOfShortestPath)
|
if (INVALID_EDGE_WEIGHT == raw_route.shortest_path_length)
|
||||||
{
|
{
|
||||||
SimpleLogger().Write(logDEBUG) << "Error occurred, single path not found";
|
SimpleLogger().Write(logDEBUG) << "Error occurred, single path not found";
|
||||||
}
|
}
|
||||||
@ -165,8 +165,8 @@ template <class DataFacadeT> class ViaRoutePlugin : public BasePlugin
|
|||||||
}
|
}
|
||||||
|
|
||||||
PhantomNodes phantom_nodes;
|
PhantomNodes phantom_nodes;
|
||||||
phantom_nodes.source_phantom = raw_route.segmentEndCoordinates.front().source_phantom;
|
phantom_nodes.source_phantom = raw_route.segment_end_coordinates.front().source_phantom;
|
||||||
phantom_nodes.target_phantom = raw_route.segmentEndCoordinates.back().target_phantom;
|
phantom_nodes.target_phantom = raw_route.segment_end_coordinates.back().target_phantom;
|
||||||
descriptor->SetConfig(descriptor_config);
|
descriptor->SetConfig(descriptor_config);
|
||||||
descriptor->Run(raw_route, phantom_nodes, facade, reply);
|
descriptor->Run(raw_route, phantom_nodes, facade, reply);
|
||||||
|
|
||||||
|
@ -315,7 +315,7 @@ public:
|
|||||||
// -- unpacked output
|
// -- unpacked output
|
||||||
raw_route_data.unpacked_path_segments.front()
|
raw_route_data.unpacked_path_segments.front()
|
||||||
);
|
);
|
||||||
raw_route_data.lengthOfShortestPath = upper_bound_to_shortest_path_distance;
|
raw_route_data.shortest_path_length = upper_bound_to_shortest_path_distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( SPECIAL_NODEID != selected_via_node ) {
|
if( SPECIAL_NODEID != selected_via_node ) {
|
||||||
@ -341,7 +341,7 @@ public:
|
|||||||
raw_route_data.unpacked_alternative
|
raw_route_data.unpacked_alternative
|
||||||
);
|
);
|
||||||
|
|
||||||
raw_route_data.lengthOfAlternativePath = length_of_via_path;
|
raw_route_data.alternative_path_length = length_of_via_path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,8 +231,8 @@ public:
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
unpacked_path.back().turnInstruction = turn_instruction;
|
unpacked_path.back().turn_instruction = turn_instruction;
|
||||||
unpacked_path.back().durationOfSegment = ed.distance;
|
unpacked_path.back().segment_duration = ed.distance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,8 +59,8 @@ public:
|
|||||||
for (const PhantomNodes & phantom_node_pair : phantom_nodes_vector)
|
for (const PhantomNodes & phantom_node_pair : phantom_nodes_vector)
|
||||||
{
|
{
|
||||||
if( phantom_node_pair.AtLeastOnePhantomNodeIsInvalid() ) {
|
if( phantom_node_pair.AtLeastOnePhantomNodeIsInvalid() ) {
|
||||||
// raw_route_data.lengthOfShortestPath = INT_MAX;
|
// raw_route_data.shortest_path_length = INT_MAX;
|
||||||
// raw_route_data.lengthOfAlternativePath = INT_MAX;
|
// raw_route_data.alternative_path_length = INT_MAX;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -212,8 +212,8 @@ public:
|
|||||||
(INVALID_EDGE_WEIGHT == local_upper_bound1) &&
|
(INVALID_EDGE_WEIGHT == local_upper_bound1) &&
|
||||||
(INVALID_EDGE_WEIGHT == local_upper_bound2)
|
(INVALID_EDGE_WEIGHT == local_upper_bound2)
|
||||||
) {
|
) {
|
||||||
raw_route_data.lengthOfShortestPath = INVALID_EDGE_WEIGHT;
|
raw_route_data.shortest_path_length = INVALID_EDGE_WEIGHT;
|
||||||
raw_route_data.lengthOfAlternativePath = INVALID_EDGE_WEIGHT;
|
raw_route_data.alternative_path_length = INVALID_EDGE_WEIGHT;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if( SPECIAL_NODEID == middle1 ) {
|
if( SPECIAL_NODEID == middle1 ) {
|
||||||
@ -393,7 +393,7 @@ public:
|
|||||||
raw_route_data.unpacked_path_segments[i]
|
raw_route_data.unpacked_path_segments[i]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
raw_route_data.lengthOfShortestPath = std::min(distance1, distance2);
|
raw_route_data.shortest_path_length = std::min(distance1, distance2);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ int main (int argc, const char * argv[]) {
|
|||||||
route_parameters.alternateRoute = true; //get an alternate route, too
|
route_parameters.alternateRoute = true; //get an alternate route, too
|
||||||
route_parameters.geometry = true; //retrieve geometry of route
|
route_parameters.geometry = true; //retrieve geometry of route
|
||||||
route_parameters.compression = true; //polyline encoding
|
route_parameters.compression = true; //polyline encoding
|
||||||
route_parameters.checkSum = UINT_MAX; //see wiki
|
route_parameters.check_sum = UINT_MAX; //see wiki
|
||||||
route_parameters.service = "viaroute"; //that's routing
|
route_parameters.service = "viaroute"; //that's routing
|
||||||
route_parameters.outputFormat = "json";
|
route_parameters.outputFormat = "json";
|
||||||
route_parameters.jsonpParameter = ""; //set for jsonp wrapping
|
route_parameters.jsonpParameter = ""; //set for jsonp wrapping
|
||||||
|
Loading…
Reference in New Issue
Block a user