First working edge based version. Still missing: GPX export; Via Points;
origin,destination on same edge, descriptions
This commit is contained in:
@@ -32,12 +32,14 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#include <google/sparse_hash_map>
|
||||
#include <google/sparsetable>
|
||||
|
||||
template< typename NodeID, typename Key, bool initialize = true >
|
||||
template< typename NodeID, typename Key >
|
||||
class ArrayStorage {
|
||||
public:
|
||||
|
||||
ArrayStorage( size_t size )
|
||||
: positions( new Key[size] ) { if(initialize) { memset(positions, 0, size*sizeof(Key));} }
|
||||
ArrayStorage( size_t size ) : positions( new Key[size] ) {
|
||||
memset(positions, 0, size*sizeof(Key));
|
||||
INFO("initializing q for " << size << " elements");
|
||||
}
|
||||
|
||||
~ArrayStorage() {
|
||||
delete[] positions;
|
||||
@@ -123,10 +125,6 @@ struct _SimpleHeapData {
|
||||
_SimpleHeapData( NodeID p ) : parent(p) { }
|
||||
};
|
||||
|
||||
//struct _NullHeapData {
|
||||
// _NullHeapData(NodeID p) {}
|
||||
//};
|
||||
|
||||
template < typename NodeID, typename Key, typename Weight, typename Data, typename IndexStorage = ArrayStorage<NodeID, NodeID> >
|
||||
class BinaryHeap {
|
||||
private:
|
||||
@@ -144,7 +142,7 @@ public:
|
||||
void Clear() {
|
||||
heap.resize( 1 );
|
||||
insertedNodes.clear();
|
||||
heap[0].weight = (std::numeric_limits< Weight >::min)();
|
||||
heap[0].weight = std::numeric_limits< Weight >::min();
|
||||
nodeIndex.Clear();
|
||||
}
|
||||
|
||||
@@ -215,7 +213,7 @@ public:
|
||||
assert( UINT_MAX != node );
|
||||
const Key index = nodeIndex[node];
|
||||
Key key = insertedNodes[index].key;
|
||||
assert ( key != 0 );
|
||||
assert ( key >= 0 );
|
||||
|
||||
insertedNodes[index].weight = weight;
|
||||
heap[key].weight = weight;
|
||||
|
||||
@@ -81,9 +81,7 @@ class DynamicGraph {
|
||||
}
|
||||
}
|
||||
|
||||
~DynamicGraph()
|
||||
{
|
||||
}
|
||||
~DynamicGraph(){ }
|
||||
|
||||
unsigned GetNumberOfNodes() const
|
||||
{
|
||||
|
||||
@@ -22,10 +22,9 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#define GRIDEDGE_H_
|
||||
|
||||
struct _GridEdge {
|
||||
_GridEdge(NodeID s, NodeID t, _Coordinate sc, _Coordinate tc) : start(s), target(t), startCoord(sc), targetCoord(tc) {}
|
||||
_GridEdge() : start(UINT_MAX), target(UINT_MAX) {}
|
||||
NodeID start;
|
||||
NodeID target;
|
||||
_GridEdge(NodeID n, _Coordinate sc, _Coordinate tc) : edgeBasedNode(n), startCoord(sc), targetCoord(tc) {}
|
||||
_GridEdge() : edgeBasedNode(UINT_MAX) {}
|
||||
NodeID edgeBasedNode;
|
||||
_Coordinate startCoord;
|
||||
_Coordinate targetCoord;
|
||||
};
|
||||
@@ -37,14 +36,10 @@ struct GridEntry {
|
||||
unsigned fileIndex;
|
||||
unsigned ramIndex;
|
||||
bool operator< ( const GridEntry& right ) const {
|
||||
if(right.edge.start != edge.start)
|
||||
return right.edge.start < edge.start;
|
||||
if(right.edge.target != edge.target)
|
||||
return right.edge.target < edge.target;
|
||||
return false;
|
||||
return (edge.edgeBasedNode < right.edge.edgeBasedNode);
|
||||
}
|
||||
bool operator==( const GridEntry& right ) const {
|
||||
return right.edge.start == edge.start && right.edge.target == edge.target;
|
||||
return right.edge.edgeBasedNode == edge.edgeBasedNode;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+69
-11
@@ -23,10 +23,10 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
|
||||
#include <cassert>
|
||||
|
||||
class Edge {
|
||||
class NodeBasedEdge {
|
||||
public:
|
||||
|
||||
bool operator< (const Edge& e) const {
|
||||
bool operator< (const NodeBasedEdge& e) const {
|
||||
if (source() == e.source()) {
|
||||
if (target() == e.target()) {
|
||||
if (weight() == e.weight()) {
|
||||
@@ -41,10 +41,10 @@ public:
|
||||
}
|
||||
|
||||
/** Default constructor. target and weight are set to 0.*/
|
||||
Edge() :
|
||||
NodeBasedEdge() :
|
||||
_source(0), _target(0), _name(0), _weight(0), forward(0), backward(0), _type(0) { assert(false); } //shall not be used.
|
||||
|
||||
explicit Edge(NodeID s, NodeID t, NodeID n, EdgeWeight w, bool f, bool b, short ty) :
|
||||
explicit NodeBasedEdge(NodeID s, NodeID t, NodeID n, EdgeWeight w, bool f, bool b, short ty) :
|
||||
_source(s), _target(t), _name(n), _weight(w), forward(f), backward(b), _type(ty) { assert(ty >= 0); }
|
||||
|
||||
NodeID target() const {return _target; }
|
||||
@@ -59,21 +59,79 @@ public:
|
||||
|
||||
NodeID _source;
|
||||
NodeID _target;
|
||||
NodeID _name:31;
|
||||
EdgeWeight _weight:31;
|
||||
bool forward:1;
|
||||
bool backward:1;
|
||||
NodeID _name;
|
||||
EdgeWeight _weight;
|
||||
bool forward;
|
||||
bool backward;
|
||||
short _type;
|
||||
};
|
||||
|
||||
struct MinimalEdgeData
|
||||
{
|
||||
class EdgeBasedEdge {
|
||||
public:
|
||||
|
||||
bool operator< (const EdgeBasedEdge& e) const {
|
||||
if (source() == e.source()) {
|
||||
if (target() == e.target()) {
|
||||
if (weight() == e.weight()) {
|
||||
return (isForward() && isBackward() &&
|
||||
((! e.isForward()) || (! e.isBackward())));
|
||||
}
|
||||
return (weight() < e.weight());
|
||||
}
|
||||
return (target() < e.target());
|
||||
}
|
||||
return (source() < e.source());
|
||||
}
|
||||
|
||||
template<class EdgeT>
|
||||
EdgeBasedEdge(const EdgeT & myEdge ) :
|
||||
_source(myEdge.source),
|
||||
_target(myEdge.target),
|
||||
_via(myEdge.data.via),
|
||||
_nameID1(myEdge.data.nameID1),
|
||||
_nameID2(myEdge.data.nameID2),
|
||||
_weight(myEdge.data.distance),
|
||||
forward(myEdge.data.forward),
|
||||
backward(myEdge.data.backward),
|
||||
_turnInstruction(myEdge.data.turnInstruction) { }
|
||||
|
||||
/** Default constructor. target and weight are set to 0.*/
|
||||
EdgeBasedEdge() :
|
||||
_source(0), _target(0), _via(0), _nameID1(0), _nameID2(0), _weight(0), forward(0), backward(0), _turnInstruction(0) { assert(false); } //shall not be used.
|
||||
|
||||
explicit EdgeBasedEdge(NodeID s, NodeID t, NodeID v, unsigned n1, unsigned n2, EdgeWeight w, bool f, bool b, short ty) :
|
||||
_source(s), _target(t), _via(v), _nameID1(n1), _nameID2(n2), _weight(w), forward(f), backward(b), _turnInstruction(ty) { assert(ty >= 0); }
|
||||
|
||||
NodeID target() const {return _target; }
|
||||
NodeID source() const {return _source; }
|
||||
EdgeWeight weight() const {return _weight; }
|
||||
NodeID via() const { return _via; }
|
||||
short turnType() const { assert(_turnInstruction >= 0); return _turnInstruction; }
|
||||
bool isBackward() const { return backward; }
|
||||
bool isForward() const { return forward; }
|
||||
|
||||
unsigned nameID1() const { return _nameID1; }
|
||||
unsigned nameID2() const { return _nameID2; }
|
||||
|
||||
NodeID _source;
|
||||
NodeID _target;
|
||||
NodeID _via;
|
||||
unsigned _nameID1;
|
||||
unsigned _nameID2;
|
||||
EdgeWeight _weight;
|
||||
bool forward;
|
||||
bool backward;
|
||||
short _turnInstruction;
|
||||
|
||||
};
|
||||
|
||||
struct MinimalEdgeData {
|
||||
public:
|
||||
EdgeWeight distance;
|
||||
bool forward;
|
||||
bool backward;
|
||||
};
|
||||
|
||||
typedef Edge ImportEdge;
|
||||
typedef NodeBasedEdge ImportEdge;
|
||||
|
||||
#endif // EDGE_H
|
||||
|
||||
+53
-100
@@ -37,6 +37,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#endif
|
||||
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <google/dense_hash_map>
|
||||
|
||||
#include "ExtractorStructs.h"
|
||||
@@ -148,16 +149,6 @@ static void GetListOfIndexesForEdgeAndGridSize(_Coordinate& start, _Coordinate&
|
||||
|
||||
template<bool WriteAccess = false>
|
||||
class NNGrid {
|
||||
private:
|
||||
struct DiskEdge {
|
||||
NodeID start;
|
||||
NodeID target;
|
||||
int slat;
|
||||
int slon;
|
||||
int tlat;
|
||||
int tlon;
|
||||
};
|
||||
|
||||
public:
|
||||
NNGrid() : cellCache(500), fileCache(500) {
|
||||
ramIndexTable.resize((1024*1024), UINT_MAX);
|
||||
@@ -167,6 +158,9 @@ public:
|
||||
}
|
||||
|
||||
NNGrid(const char* rif, const char* _i, unsigned numberOfThreads = omp_get_num_procs()): cellCache(500), fileCache(500) {
|
||||
if(WriteAccess) {
|
||||
ERR("Not available in Write mode");
|
||||
}
|
||||
iif = std::string(_i);
|
||||
ramIndexTable.resize((1024*1024), UINT_MAX);
|
||||
ramInFile.open(rif, std::ios::in | std::ios::binary);
|
||||
@@ -183,7 +177,7 @@ public:
|
||||
void OpenIndexFiles() {
|
||||
assert(ramInFile.is_open());
|
||||
|
||||
for(int i = 0; i < 1024*1024; i++) {
|
||||
for(int i = 0; i < 1024*1024; ++i) {
|
||||
unsigned temp;
|
||||
ramInFile.read((char*)&temp, sizeof(unsigned));
|
||||
ramIndexTable[i] = temp;
|
||||
@@ -194,19 +188,16 @@ public:
|
||||
template<typename EdgeT, typename NodeInfoT>
|
||||
void ConstructGrid(std::vector<EdgeT> & edgeList, vector<NodeInfoT> * int2ExtNodeMap, char * ramIndexOut, char * fileIndexOut) {
|
||||
Percent p(edgeList.size());
|
||||
for(NodeID i = 0; i < edgeList.size(); i++) {
|
||||
for(NodeID i = 0; i < edgeList.size(); ++i) {
|
||||
p.printIncrement();
|
||||
if( edgeList[i].isLocatable() == false )
|
||||
continue;
|
||||
EdgeT edge = edgeList[i];
|
||||
EdgeT & edge = edgeList[i];
|
||||
|
||||
int slat = 100000*lat2y(static_cast<double>(int2ExtNodeMap->at(edge.source()).lat)/100000.);
|
||||
int slon = int2ExtNodeMap->at(edge.source()).lon;
|
||||
int tlat = 100000*lat2y(static_cast<double>(int2ExtNodeMap->at(edge.target()).lat)/100000.);
|
||||
int tlon = int2ExtNodeMap->at(edge.target()).lon;
|
||||
int slat = 100000*lat2y(edge.lat1/100000.);
|
||||
int slon = edge.lon1;
|
||||
int tlat = 100000*lat2y(edge.lat2/100000.);
|
||||
int tlon = edge.lon2;
|
||||
AddEdge( _GridEdge(
|
||||
edgeList[i].source(),
|
||||
edgeList[i].target(),
|
||||
edge.id,
|
||||
_Coordinate(slat, slon),
|
||||
_Coordinate(tlat, tlon) )
|
||||
);
|
||||
@@ -225,7 +216,7 @@ public:
|
||||
unsigned maxNumberOfRAMCellElements = 0;
|
||||
cout << "writing data ..." << flush;
|
||||
p.reinit(entries->size());
|
||||
for(stxxl::vector<GridEntry>::iterator vt = entries->begin(); vt != entries->end(); vt++) {
|
||||
for(stxxl::vector<GridEntry>::iterator vt = entries->begin(); vt != entries->end(); ++vt) {
|
||||
p.printIncrement();
|
||||
if(vt->ramIndex != indexInRamTable) {
|
||||
unsigned numberOfBytesInCell = FillCell(entriesInFileWithRAMSameIndex, lastPositionInIndexFile);
|
||||
@@ -247,7 +238,7 @@ public:
|
||||
|
||||
assert(entriesInFileWithRAMSameIndex.size() == 0);
|
||||
|
||||
for(int i = 0; i < 1024*1024; i++) {
|
||||
for(int i = 0; i < 1024*1024; ++i) {
|
||||
if(ramIndexTable[i] != UINT_MAX) {
|
||||
numberOfUsedCells--;
|
||||
}
|
||||
@@ -259,17 +250,17 @@ public:
|
||||
//Serialize RAM Index
|
||||
ofstream ramFile(ramIndexOut, std::ios::out | std::ios::binary | std::ios::trunc);
|
||||
//write 4 MB of index Table in RAM
|
||||
for(int i = 0; i < 1024*1024; i++)
|
||||
for(int i = 0; i < 1024*1024; ++i)
|
||||
ramFile.write((char *)&ramIndexTable[i], sizeof(unsigned) );
|
||||
//close ram index file
|
||||
ramFile.close();
|
||||
}
|
||||
|
||||
bool GetStartAndDestNodesOfEdge(const _Coordinate& coord, NodesOfEdge& nodesOfEdge) {
|
||||
bool GetEdgeBasedStartNode(const _Coordinate& coord, NodesOfEdge& nodesOfEdge) {
|
||||
_Coordinate startCoord(100000*(lat2y(static_cast<double>(coord.lat)/100000.)), coord.lon);
|
||||
/** search for point on edge next to source */
|
||||
unsigned fileIndex = GetFileIndexForLatLon(startCoord.lat, startCoord.lon);
|
||||
std::vector<_Edge> candidates;
|
||||
std::vector<_GridEdge> candidates;
|
||||
|
||||
for(int j = -32768; j < (32768+1); j+=32768) {
|
||||
for(int i = -1; i < 2; i++){
|
||||
@@ -277,13 +268,12 @@ public:
|
||||
}
|
||||
}
|
||||
_Coordinate tmp;
|
||||
double dist = (numeric_limits<double>::max)();
|
||||
for(std::vector<_Edge>::iterator it = candidates.begin(); it != candidates.end(); it++) {
|
||||
double dist = numeric_limits<double>::max();
|
||||
BOOST_FOREACH(_GridEdge candidate, candidates) {
|
||||
double r = 0.;
|
||||
double tmpDist = ComputeDistance(startCoord, it->startCoord, it->targetCoord, tmp, &r);
|
||||
double tmpDist = ComputeDistance(startCoord, candidate.startCoord, candidate.targetCoord, tmp, &r);
|
||||
if(tmpDist < dist) {
|
||||
nodesOfEdge.startID = it->start;
|
||||
nodesOfEdge.destID = it->target;
|
||||
nodesOfEdge.edgeBasedNode = candidate.edgeBasedNode;
|
||||
nodesOfEdge.ratio = r;
|
||||
dist = tmpDist;
|
||||
nodesOfEdge.projectedPoint.lat = round(100000*(y2lat(static_cast<double>(tmp.lat)/100000.)));
|
||||
@@ -297,11 +287,12 @@ public:
|
||||
}
|
||||
|
||||
bool FindPhantomNodeForCoordinate( const _Coordinate & location, PhantomNode & resultNode) {
|
||||
INFO("FindPhantomNodeForCoordinate");
|
||||
bool foundNode = false;
|
||||
_Coordinate startCoord(100000*(lat2y(static_cast<double>(location.lat)/100000.)), location.lon);
|
||||
/** search for point on edge close to source */
|
||||
unsigned fileIndex = GetFileIndexForLatLon(startCoord.lat, startCoord.lon);
|
||||
std::vector<_Edge> candidates;
|
||||
std::vector<_GridEdge> candidates;
|
||||
|
||||
for(int j = -32768; j < (32768+1); j+=32768) {
|
||||
for(int i = -1; i < 2; i++){
|
||||
@@ -311,13 +302,16 @@ public:
|
||||
|
||||
_Coordinate tmp;
|
||||
double dist = (numeric_limits<double>::max)();
|
||||
for(std::vector<_Edge>::iterator it = candidates.begin(); it != candidates.end(); it++) {
|
||||
BOOST_FOREACH(_GridEdge candidate, candidates) {
|
||||
double r = 0.;
|
||||
double tmpDist = ComputeDistance(startCoord, it->startCoord, it->targetCoord, tmp, &r);
|
||||
double tmpDist = ComputeDistance(startCoord, candidate.startCoord, candidate.targetCoord, tmp, &r);
|
||||
if((tmpDist == dist) && 1 == std::abs((int)candidate.edgeBasedNode-(int)resultNode.edgeBasedNode)) {
|
||||
resultNode.isBidirected = true;
|
||||
resultNode.edgeBasedNode = std::min(candidate.edgeBasedNode, resultNode.edgeBasedNode);
|
||||
}
|
||||
if(tmpDist < dist) {
|
||||
// std::cout << "[debug] start distance " << (it - candidates.begin()) << " " << tmpDist << std::endl;
|
||||
resultNode.startNode = it->start;
|
||||
resultNode.targetNode = it->target;
|
||||
resultNode.isBidirected = false;
|
||||
resultNode.edgeBasedNode = candidate.edgeBasedNode;
|
||||
resultNode.ratio = r;
|
||||
dist = tmpDist;
|
||||
resultNode.location.lat = round(100000*(y2lat(static_cast<double>(tmp.lat)/100000.)));
|
||||
@@ -334,9 +328,9 @@ public:
|
||||
FindPhantomNodeForCoordinate( target, routingStarts.targetPhantom) );
|
||||
}
|
||||
|
||||
void FindNearestNodeInGraph(const _Coordinate& inputCoordinate, _Coordinate& outputCoordinate) {
|
||||
void FindNearestCoordinateOnEdgeInNodeBasedGraph(const _Coordinate& inputCoordinate, _Coordinate& outputCoordinate) {
|
||||
unsigned fileIndex = GetFileIndexForLatLon(100000*(lat2y(static_cast<double>(inputCoordinate.lat)/100000.)), inputCoordinate.lon);
|
||||
std::vector<_Edge> candidates;
|
||||
std::vector<_GridEdge> candidates;
|
||||
for(int j = -32768; j < (32768+1); j+=32768) {
|
||||
for(int i = -1; i < 2; i++) {
|
||||
GetContentsOfFileBucket(fileIndex+i+j, candidates);
|
||||
@@ -344,9 +338,9 @@ public:
|
||||
}
|
||||
_Coordinate tmp;
|
||||
double dist = (numeric_limits<double>::max)();
|
||||
for(std::vector<_Edge>::iterator it = candidates.begin(); it != candidates.end(); it++) {
|
||||
BOOST_FOREACH(_GridEdge candidate, candidates) {
|
||||
double r = 0.;
|
||||
double tmpDist = ComputeDistance(inputCoordinate, it->startCoord, it->targetCoord, tmp, &r);
|
||||
double tmpDist = ComputeDistance(inputCoordinate, candidate.startCoord, candidate.targetCoord, tmp, &r);
|
||||
if(tmpDist < dist) {
|
||||
dist = tmpDist;
|
||||
outputCoordinate = tmp;
|
||||
@@ -359,7 +353,7 @@ public:
|
||||
_Coordinate startCoord(100000*(lat2y(static_cast<double>(inputCoordinate.lat)/100000.)), inputCoordinate.lon);
|
||||
unsigned fileIndex = GetFileIndexForLatLon(startCoord.lat, startCoord.lon);
|
||||
|
||||
std::vector<_Edge> candidates;
|
||||
std::vector<_GridEdge> candidates;
|
||||
for(int j = -32768; j < (32768+1); j+=32768) {
|
||||
for(int i = -1; i < 2; i++) {
|
||||
GetContentsOfFileBucket(fileIndex+i+j, candidates);
|
||||
@@ -367,9 +361,9 @@ public:
|
||||
}
|
||||
_Coordinate tmp;
|
||||
double dist = (numeric_limits<double>::max)();
|
||||
for(std::vector<_Edge>::iterator it = candidates.begin(); it != candidates.end(); it++) {
|
||||
BOOST_FOREACH(_GridEdge candidate, candidates) {
|
||||
double r = 0.;
|
||||
double tmpDist = ComputeDistance(startCoord, it->startCoord, it->targetCoord, tmp, &r);
|
||||
double tmpDist = ComputeDistance(startCoord, candidate.startCoord, candidate.targetCoord, tmp, &r);
|
||||
if(tmpDist < dist) {
|
||||
dist = tmpDist;
|
||||
outputCoordinate.lat = round(100000*(y2lat(static_cast<double>(tmp.lat)/100000.)));
|
||||
@@ -381,8 +375,7 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
unsigned FillCell(std::vector<GridEntry>& entriesWithSameRAMIndex, unsigned fileOffset )
|
||||
{
|
||||
unsigned FillCell(std::vector<GridEntry>& entriesWithSameRAMIndex, unsigned fileOffset ) {
|
||||
vector<char> * tmpBuffer = new vector<char>();
|
||||
tmpBuffer->resize(32*32*4096,0);
|
||||
unsigned indexIntoTmpBuffer = 0;
|
||||
@@ -408,8 +401,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
for(unsigned i = 0; i < entriesWithSameRAMIndex.size() -1; i++)
|
||||
{
|
||||
for(unsigned i = 0; i < entriesWithSameRAMIndex.size() -1; ++i) {
|
||||
assert(entriesWithSameRAMIndex[i].ramIndex== entriesWithSameRAMIndex[i+1].ramIndex);
|
||||
}
|
||||
|
||||
@@ -471,7 +463,7 @@ private:
|
||||
|
||||
unsigned FlushEntriesWithSameFileIndexToBuffer( std::vector<GridEntry> &vectorWithSameFileIndex, vector<char> * tmpBuffer, const unsigned index)
|
||||
{
|
||||
tmpBuffer->resize(tmpBuffer->size()+(sizeof(NodeID)+sizeof(NodeID)+4*sizeof(int)+sizeof(unsigned))*vectorWithSameFileIndex.size() );
|
||||
tmpBuffer->resize(tmpBuffer->size()+(sizeof(_GridEdge)*vectorWithSameFileIndex.size()) );
|
||||
unsigned counter = 0;
|
||||
unsigned max = UINT_MAX;
|
||||
|
||||
@@ -482,44 +474,12 @@ private:
|
||||
}
|
||||
|
||||
sort( vectorWithSameFileIndex.begin(), vectorWithSameFileIndex.end() );
|
||||
std::vector<GridEntry>::const_iterator newEnd = unique(vectorWithSameFileIndex.begin(), vectorWithSameFileIndex.end());
|
||||
for(std::vector<GridEntry>::const_iterator et = vectorWithSameFileIndex.begin(); et != newEnd; et++)
|
||||
{
|
||||
char * start = (char *)&et->edge.start;
|
||||
for(unsigned i = 0; i < sizeof(NodeID); i++)
|
||||
{
|
||||
tmpBuffer->at(index+counter) = start[i];
|
||||
counter++;
|
||||
}
|
||||
char * target = (char *)&et->edge.target;
|
||||
for(unsigned i = 0; i < sizeof(NodeID); i++)
|
||||
{
|
||||
tmpBuffer->at(index+counter) = target[i];
|
||||
counter++;
|
||||
}
|
||||
char * slat = (char *) &(et->edge.startCoord.lat);
|
||||
for(unsigned i = 0; i < sizeof(int); i++)
|
||||
{
|
||||
tmpBuffer->at(index+counter) = slat[i];
|
||||
counter++;
|
||||
}
|
||||
char * slon = (char *) &(et->edge.startCoord.lon);
|
||||
for(unsigned i = 0; i < sizeof(int); i++)
|
||||
{
|
||||
tmpBuffer->at(index+counter) = slon[i];
|
||||
counter++;
|
||||
}
|
||||
char * tlat = (char *) &(et->edge.targetCoord.lat);
|
||||
for(unsigned i = 0; i < sizeof(int); i++)
|
||||
{
|
||||
tmpBuffer->at(index+counter) = tlat[i];
|
||||
counter++;
|
||||
}
|
||||
char * tlon = (char *) &(et->edge.targetCoord.lon);
|
||||
for(unsigned i = 0; i < sizeof(int); i++)
|
||||
{
|
||||
tmpBuffer->at(index+counter) = tlon[i];
|
||||
counter++;
|
||||
vectorWithSameFileIndex.erase(unique(vectorWithSameFileIndex.begin(), vectorWithSameFileIndex.end()), vectorWithSameFileIndex.end());
|
||||
BOOST_FOREACH(GridEntry entry, vectorWithSameFileIndex) {
|
||||
char * data = (char *)&(entry.edge);
|
||||
for(unsigned i = 0; i < sizeof(_GridEdge); ++i) {
|
||||
tmpBuffer->at(index+counter) = data[i];
|
||||
++counter;
|
||||
}
|
||||
}
|
||||
char * umax = (char *) &max;
|
||||
@@ -531,7 +491,7 @@ private:
|
||||
return counter;
|
||||
}
|
||||
|
||||
void GetContentsOfFileBucket(const unsigned fileIndex, std::vector<_Edge>& result) {
|
||||
void GetContentsOfFileBucket(const unsigned fileIndex, std::vector<_GridEdge>& result) {
|
||||
unsigned ramIndex = GetRAMIndexFromFileIndex(fileIndex);
|
||||
unsigned startIndexInFile = ramIndexTable[ramIndex];
|
||||
if(startIndexInFile == UINT_MAX) {
|
||||
@@ -569,19 +529,12 @@ private:
|
||||
|
||||
std::ifstream localStream(iif.c_str(), std::ios::in | std::ios::binary);
|
||||
localStream.seekg(position);
|
||||
DiskEdge diskEdge;
|
||||
_GridEdge gridEdge;
|
||||
do {
|
||||
localStream.read((char *)&(diskEdge), sizeof(DiskEdge));
|
||||
if(localStream.eof() || diskEdge.start == UINT_MAX)
|
||||
localStream.read((char *)&(gridEdge), sizeof(_GridEdge));
|
||||
if(localStream.eof() || gridEdge.edgeBasedNode == UINT_MAX)
|
||||
break;
|
||||
|
||||
_Edge e(diskEdge.start, diskEdge.target);
|
||||
e.startCoord.lat = diskEdge.slat;
|
||||
e.startCoord.lon = diskEdge.slon;
|
||||
e.targetCoord.lat = diskEdge.tlat;
|
||||
e.targetCoord.lon = diskEdge.tlon;
|
||||
|
||||
result.push_back(e);
|
||||
result.push_back(gridEdge);
|
||||
} while(true);
|
||||
localStream.close();
|
||||
|
||||
@@ -590,7 +543,7 @@ private:
|
||||
void AddEdge(_GridEdge edge) {
|
||||
std::vector<std::pair<unsigned, unsigned> > indexList;
|
||||
GetListOfIndexesForEdgeAndGridSize(edge.startCoord, edge.targetCoord, indexList);
|
||||
for(unsigned i = 0; i < indexList.size(); i++) {
|
||||
for(unsigned i = 0; i < indexList.size(); ++i) {
|
||||
entries->push_back(GridEntry(edge, indexList[i].first, indexList[i].second));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <limits>
|
||||
#include <climits>
|
||||
|
||||
#include "../typedefs.h"
|
||||
|
||||
@@ -33,7 +33,7 @@ struct NodeCoords {
|
||||
typedef int value_type; //type of lat,lons
|
||||
|
||||
NodeCoords(int _lat, int _lon, NodeT _id) : lat(_lat), lon(_lon), id(_id) {}
|
||||
NodeCoords() : lat(UINT_MAX), lon(UINT_MAX), id(UINT_MAX) {}
|
||||
NodeCoords() : lat(INT_MAX), lon(INT_MAX), id(UINT_MAX) {}
|
||||
int lat;
|
||||
int lon;
|
||||
NodeT id;
|
||||
|
||||
@@ -31,27 +31,30 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
|
||||
class NodeInformationHelpDesk{
|
||||
public:
|
||||
NodeInformationHelpDesk(const char* ramIndexInput, const char* fileIndexInput) {
|
||||
NodeInformationHelpDesk(const char* ramIndexInput, const char* fileIndexInput, unsigned _numberOfNodes) : numberOfNodes(_numberOfNodes) {
|
||||
readOnlyGrid = new ReadOnlyGrid(ramIndexInput,fileIndexInput);
|
||||
int2ExtNodeMap = new vector<_Coordinate>();
|
||||
numberOfNodes = 0;
|
||||
int2ExtNodeMap->reserve(numberOfNodes);
|
||||
assert(0 == int2ExtNodeMap->size());
|
||||
}
|
||||
|
||||
~NodeInformationHelpDesk() {
|
||||
delete int2ExtNodeMap;
|
||||
delete readOnlyGrid;
|
||||
}
|
||||
void initNNGrid(ifstream& in) {
|
||||
while(!in.eof()) {
|
||||
while(!in.eof()) {
|
||||
NodeInfo b;
|
||||
in.read((char *)&b, sizeof(b));
|
||||
int2ExtNodeMap->push_back(_Coordinate(b.lat, b.lon));
|
||||
numberOfNodes++;
|
||||
}
|
||||
in.close();
|
||||
readOnlyGrid->OpenIndexFiles();
|
||||
}
|
||||
|
||||
inline int getLatitudeOfNode(const NodeID node) const { return int2ExtNodeMap->at(node).lat; }
|
||||
inline int getLatitudeOfNode(const NodeID node) const {
|
||||
return int2ExtNodeMap->at(node).lat;
|
||||
}
|
||||
|
||||
inline int getLongitudeOfNode(const NodeID node) const { return int2ExtNodeMap->at(node).lon; }
|
||||
|
||||
@@ -59,7 +62,7 @@ public:
|
||||
NodeID getNumberOfNodes2() const { return int2ExtNodeMap->size(); }
|
||||
|
||||
inline void FindNearestNodeCoordForLatLon(const _Coordinate& coord, _Coordinate& result) {
|
||||
readOnlyGrid->FindNearestNodeInGraph(coord, result);
|
||||
readOnlyGrid->FindNearestCoordinateOnEdgeInNodeBasedGraph(coord, result);
|
||||
}
|
||||
bool FindPhantomNodeForCoordinate( const _Coordinate & location, PhantomNode & resultNode) {
|
||||
return readOnlyGrid->FindPhantomNodeForCoordinate(location, resultNode);
|
||||
@@ -71,7 +74,7 @@ public:
|
||||
}
|
||||
|
||||
inline bool GetStartAndDestNodesOfEdge(const _Coordinate& coord, NodesOfEdge& nodesOfEdge) {
|
||||
return readOnlyGrid->GetStartAndDestNodesOfEdge(coord, nodesOfEdge);
|
||||
return readOnlyGrid->GetEdgeBasedStartNode(coord, nodesOfEdge);
|
||||
}
|
||||
|
||||
inline void FindNearestPointOnEdge(const _Coordinate & input, _Coordinate& output){
|
||||
|
||||
@@ -62,7 +62,7 @@ class PBFParser : public BaseParser<_Node, _RawRestrictionContainer, _Way> {
|
||||
|
||||
public:
|
||||
PBFParser(const char * fileName)
|
||||
: threadDataQueue( new concurrent_queue<_ThreadData*>(25) ) { /* Max 25 items in queue */
|
||||
: threadDataQueue( new ConcurrentQueue<_ThreadData*>(25) ) { /* Max 25 items in queue */
|
||||
GOOGLE_PROTOBUF_VERIFY_VERSION;
|
||||
input.open(fileName, std::ios::in | std::ios::binary);
|
||||
|
||||
@@ -525,7 +525,7 @@ private:
|
||||
std::fstream input;
|
||||
|
||||
/* ThreadData Queue */
|
||||
concurrent_queue < _ThreadData* >* threadDataQueue;
|
||||
ConcurrentQueue < _ThreadData* >* threadDataQueue;
|
||||
};
|
||||
|
||||
#endif /* PBFPARSER_H_ */
|
||||
|
||||
@@ -24,15 +24,13 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#include "ExtractorStructs.h"
|
||||
|
||||
struct PhantomNode {
|
||||
PhantomNode() : startNode(UINT_MAX), targetNode(UINT_MAX), ratio(1.) {}
|
||||
|
||||
NodeID startNode;
|
||||
NodeID targetNode;
|
||||
PhantomNode() : isBidirected(false), edgeBasedNode(UINT_MAX), ratio(1.) {}
|
||||
bool isBidirected;
|
||||
NodeID edgeBasedNode;
|
||||
double ratio;
|
||||
_Coordinate location;
|
||||
void Reset() {
|
||||
startNode = UINT_MAX;
|
||||
targetNode = UINT_MAX;
|
||||
edgeBasedNode = UINT_MAX;
|
||||
ratio = 1.;
|
||||
location.Reset();
|
||||
}
|
||||
@@ -47,28 +45,25 @@ struct PhantomNodes {
|
||||
targetPhantom.Reset();
|
||||
}
|
||||
|
||||
bool PhantomsAreOnSameEdge() const {
|
||||
return ((startPhantom.startNode == targetPhantom.startNode && startPhantom.targetNode == targetPhantom.targetNode ) || (startPhantom.startNode == targetPhantom.targetNode && targetPhantom.startNode == startPhantom.targetNode));
|
||||
bool PhantomsAreOnSameNodeBasedEdge() const {
|
||||
return (startPhantom.edgeBasedNode == targetPhantom.edgeBasedNode);
|
||||
}
|
||||
|
||||
bool AtLeastOnePhantomNodeIsUINTMAX() const {
|
||||
return !(startPhantom.startNode == UINT_MAX || startPhantom.targetNode == UINT_MAX || targetPhantom.startNode == UINT_MAX || targetPhantom.targetNode == UINT_MAX);
|
||||
return !(startPhantom.edgeBasedNode == UINT_MAX || targetPhantom.edgeBasedNode == UINT_MAX);
|
||||
}
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream &out, const PhantomNodes & pn){
|
||||
out << "startNode1: " << pn.startPhantom.startNode << std::endl;
|
||||
out << "startNode2: " << pn.startPhantom.targetNode << std::endl;
|
||||
out << "targetNode1: " << pn.targetPhantom.startNode << std::endl;
|
||||
out << "targetNode2: " << pn.targetPhantom.targetNode << std::endl;
|
||||
out << "Node1: " << pn.startPhantom.edgeBasedNode << std::endl;
|
||||
out << "Node2: " << pn.targetPhantom.edgeBasedNode << std::endl;
|
||||
out << "startCoord: " << pn.startPhantom.location << std::endl;
|
||||
out << "targetCoord: " << pn.targetPhantom.location << std::endl;
|
||||
return out;
|
||||
}
|
||||
|
||||
struct NodesOfEdge {
|
||||
NodeID startID;
|
||||
NodeID destID;
|
||||
NodeID edgeBasedNode;
|
||||
double ratio;
|
||||
_Coordinate projectedPoint;
|
||||
};
|
||||
|
||||
+237
-308
@@ -24,6 +24,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#include <climits>
|
||||
#include <deque>
|
||||
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
#include "BinaryHeap.h"
|
||||
#include "PhantomNodes.h"
|
||||
#include "../Util/StringUtil.h"
|
||||
@@ -54,51 +56,22 @@ struct _Statistics {
|
||||
double preprocTime;
|
||||
};
|
||||
|
||||
struct _InsertedNodes {
|
||||
NodeID forward1;
|
||||
NodeID forward2;
|
||||
NodeID backward1;
|
||||
NodeID backward2;
|
||||
_InsertedNodes() : forward1(UINT_MAX), forward2(UINT_MAX), backward1(UINT_MAX), backward2(UINT_MAX) {};
|
||||
void BackInsert(NodeID n) {
|
||||
if(backward1 == UINT_MAX) {
|
||||
backward1 = n;
|
||||
} else {
|
||||
backward2 = n;
|
||||
}
|
||||
}
|
||||
void ForwInsert( NodeID n) {
|
||||
if(forward1 == UINT_MAX) {
|
||||
forward1 = n;
|
||||
} else {
|
||||
forward2 = n;
|
||||
}
|
||||
}
|
||||
typedef boost::thread_specific_ptr<BinaryHeap< NodeID, NodeID, int, _HeapData > > HeapPtr;
|
||||
|
||||
inline bool isForwardInserted(NodeID n) {
|
||||
return forward1 == n || forward2 == n;
|
||||
}
|
||||
|
||||
inline bool isBackwardInserted (NodeID n) {
|
||||
return backward1 == n || backward2 == n;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
typedef BinaryHeap< NodeID, int, int, _HeapData, ArrayStorage<NodeID, NodeID> > _Heap;
|
||||
|
||||
template<typename EdgeData, typename GraphT, typename NodeHelperT = NodeInformationHelpDesk>
|
||||
template<class EdgeData, class GraphT>
|
||||
class SearchEngine {
|
||||
private:
|
||||
const GraphT * _graph;
|
||||
NodeHelperT * nodeHelpDesk;
|
||||
const GraphT * _graph;
|
||||
NodeInformationHelpDesk * nodeHelpDesk;
|
||||
std::vector<string> * _names;
|
||||
static HeapPtr _forwardHeap;
|
||||
static HeapPtr _backwardHeap;
|
||||
inline double absDouble(double input) { if(input < 0) return input*(-1); else return input;}
|
||||
public:
|
||||
SearchEngine(GraphT * g, NodeHelperT * nh, vector<string> * n = new vector<string>()) : _graph(g), nodeHelpDesk(nh), _names(n) {}
|
||||
SearchEngine(GraphT * g, NodeInformationHelpDesk * nh, vector<string> * n = new vector<string>()) : _graph(g), nodeHelpDesk(nh), _names(n) {}
|
||||
~SearchEngine() {}
|
||||
|
||||
inline const void getCoordinatesForNodeID(NodeID id, _Coordinate& result) const {
|
||||
inline const void GetCoordinatesForNodeID(NodeID id, _Coordinate& result) const {
|
||||
result.lat = nodeHelpDesk->getLatitudeOfNode(id);
|
||||
result.lon = nodeHelpDesk->getLongitudeOfNode(id);
|
||||
}
|
||||
@@ -107,246 +80,197 @@ public:
|
||||
return nodeHelpDesk->getNumberOfNodes();
|
||||
}
|
||||
|
||||
unsigned int ComputeRoute(PhantomNodes &phantomNodes, vector<_PathData > & path) {
|
||||
inline void InitializeThreadLocalStorageIfNecessary() {
|
||||
if(!_forwardHeap.get())
|
||||
_forwardHeap.reset(new BinaryHeap< NodeID, NodeID, int, _HeapData >(nodeHelpDesk->getNumberOfNodes()));
|
||||
else
|
||||
_forwardHeap->Clear();
|
||||
|
||||
bool startEdgeIsReversedInGraph = false;
|
||||
bool targetEdgeIsReversed = false;
|
||||
if(!_backwardHeap.get())
|
||||
_backwardHeap.reset(new BinaryHeap< NodeID, NodeID, int, _HeapData >(nodeHelpDesk->getNumberOfNodes()));
|
||||
else
|
||||
_backwardHeap->Clear();
|
||||
}
|
||||
|
||||
unsigned int _upperbound = UINT_MAX;
|
||||
unsigned int ComputeRoute(PhantomNodes & phantomNodes, vector<_PathData> & path) {
|
||||
unsigned int _upperbound = UINT_MAX;
|
||||
if(!phantomNodes.AtLeastOnePhantomNodeIsUINTMAX())
|
||||
return _upperbound;
|
||||
|
||||
if(!phantomNodes.AtLeastOnePhantomNodeIsUINTMAX())
|
||||
return _upperbound;
|
||||
InitializeThreadLocalStorageIfNecessary();
|
||||
NodeID middle = ( NodeID ) UINT_MAX;
|
||||
if(phantomNodes.PhantomsAreOnSameNodeBasedEdge()){
|
||||
//TODO: Hier behandeln, dass Start und Ziel auf der gleichen Originalkante liegen
|
||||
INFO("TODO: Start and target are on same edge")
|
||||
return _upperbound;
|
||||
}
|
||||
//insert start and/or target node of start edge
|
||||
_forwardHeap->Insert(phantomNodes.startPhantom.edgeBasedNode, 0, phantomNodes.startPhantom.edgeBasedNode);
|
||||
// INFO("Inserting start1: " << phantomNodes.startPhantom.edgeBasedNode);
|
||||
if(phantomNodes.startPhantom.isBidirected) {
|
||||
_forwardHeap->Insert(phantomNodes.startPhantom.edgeBasedNode+1, 0, phantomNodes.startPhantom.edgeBasedNode+1);
|
||||
// INFO("Inserting start2: " << phantomNodes.startPhantom.edgeBasedNode+1);
|
||||
}
|
||||
|
||||
EdgeID sourceEdgeID = _graph->FindEdgeIndicateIfReverse( phantomNodes.startPhantom.startNode, phantomNodes.startPhantom.targetNode, startEdgeIsReversedInGraph);
|
||||
if(sourceEdgeID == UINT_MAX){
|
||||
//insert start and/or target node of target edge id
|
||||
_backwardHeap->Insert(phantomNodes.targetPhantom.edgeBasedNode, 0, phantomNodes.targetPhantom.edgeBasedNode);
|
||||
// INFO("Inserting target1: " << phantomNodes.targetPhantom.edgeBasedNode);
|
||||
if(phantomNodes.targetPhantom.isBidirected) {
|
||||
_backwardHeap->Insert(phantomNodes.targetPhantom.edgeBasedNode+1, 0, phantomNodes.targetPhantom.edgeBasedNode+1);
|
||||
// INFO("Inserting target2: " << phantomNodes.targetPhantom.edgeBasedNode+1);
|
||||
}
|
||||
|
||||
while(_forwardHeap->Size() + _backwardHeap->Size() > 0){
|
||||
if(_forwardHeap->Size() > 0){
|
||||
_RoutingStep(_forwardHeap, _backwardHeap, true, &middle, &_upperbound);
|
||||
}
|
||||
if(_backwardHeap->Size() > 0){
|
||||
_RoutingStep(_backwardHeap, _forwardHeap, false, &middle, &_upperbound);
|
||||
}
|
||||
}
|
||||
// INFO("bidirectional search iteration ended: " << _forwardHeap->Size() << "," << _backwardHeap->Size() << ", dist: " << _upperbound);
|
||||
|
||||
if ( _upperbound == UINT_MAX ) {
|
||||
return _upperbound;
|
||||
}
|
||||
NodeID pathNode = middle;
|
||||
deque<NodeID> packedPath;
|
||||
while(phantomNodes.startPhantom.edgeBasedNode != pathNode && (!phantomNodes.startPhantom.isBidirected || phantomNodes.startPhantom.edgeBasedNode+1 != pathNode) ) {
|
||||
pathNode = _forwardHeap->GetData(pathNode).parent;
|
||||
packedPath.push_front(pathNode);
|
||||
}
|
||||
// INFO("Finished getting packed forward path: " << packedPath.size());
|
||||
packedPath.push_back(middle);
|
||||
pathNode = middle;
|
||||
while(phantomNodes.targetPhantom.edgeBasedNode != pathNode && (!phantomNodes.targetPhantom.isBidirected || phantomNodes.targetPhantom.edgeBasedNode+1 != pathNode)) {
|
||||
pathNode = _backwardHeap->GetData(pathNode).parent;
|
||||
packedPath.push_back(pathNode);
|
||||
}
|
||||
// INFO("Finished getting packed path: " << packedPath.size());
|
||||
for(deque<NodeID>::size_type i = 0;i < packedPath.size() - 1;i++){
|
||||
_UnpackEdge(packedPath[i], packedPath[i + 1], path);
|
||||
}
|
||||
return _upperbound;
|
||||
}
|
||||
|
||||
EdgeID targetEdgeID = _graph->FindEdgeIndicateIfReverse( phantomNodes.targetPhantom.startNode, phantomNodes.targetPhantom.targetNode, targetEdgeIsReversed);
|
||||
if(targetEdgeID == UINT_MAX){
|
||||
return _upperbound;
|
||||
}
|
||||
unsigned int ComputeDistanceBetweenNodes(NodeID start, NodeID target) {
|
||||
InitializeThreadLocalStorageIfNecessary();
|
||||
NodeID middle(UINT_MAX);
|
||||
unsigned int _upperbound = UINT_MAX;
|
||||
_forwardHeap->Insert(start, 0, start);
|
||||
_backwardHeap->Insert(target, 0, target);
|
||||
while(_forwardHeap->Size() + _backwardHeap->Size() > 0){
|
||||
if(_forwardHeap->Size() > 0){
|
||||
_RoutingStep(_forwardHeap, _backwardHeap, true, &middle, &_upperbound);
|
||||
}
|
||||
if(_backwardHeap->Size() > 0){
|
||||
_RoutingStep(_backwardHeap, _forwardHeap, false, &middle, &_upperbound);
|
||||
}
|
||||
}
|
||||
|
||||
_InsertedNodes _insertedNodes;
|
||||
return _upperbound;
|
||||
}
|
||||
|
||||
_Heap _forwardHeap(nodeHelpDesk->getNumberOfNodes());
|
||||
_Heap _backwardHeap(nodeHelpDesk->getNumberOfNodes());
|
||||
unsigned int ComputeDistanceBetweenNodesWithStats(NodeID start, NodeID target, _Statistics & stats) {
|
||||
InitializeThreadLocalStorageIfNecessary();
|
||||
NodeID middle(UINT_MAX);
|
||||
unsigned int _upperbound = UINT_MAX;
|
||||
_forwardHeap->Insert(start, 0, start);
|
||||
_backwardHeap->Insert(target, 0, target);
|
||||
stats.insertedNodes += 2;
|
||||
while(_forwardHeap->Size() + _backwardHeap->Size() > 0){
|
||||
if(_forwardHeap->Size() > 0){
|
||||
_RoutingStepWithStats(_forwardHeap, _backwardHeap, true, &middle, &_upperbound, stats);
|
||||
}
|
||||
if(_backwardHeap->Size() > 0){
|
||||
_RoutingStepWithStats(_backwardHeap, _forwardHeap, false, &middle, &_upperbound, stats);
|
||||
}
|
||||
}
|
||||
|
||||
NodeID middle = ( NodeID ) UINT_MAX;
|
||||
return _upperbound;
|
||||
}
|
||||
|
||||
if( phantomNodes.PhantomsAreOnSameEdge() ) {
|
||||
const EdgeData& currentEdgeData = _graph->GetEdgeData(sourceEdgeID);
|
||||
EdgeWeight w = currentEdgeData.distance;
|
||||
inline unsigned int findNearestNodeForLatLon(const _Coordinate & coord, _Coordinate & result) const {
|
||||
nodeHelpDesk->FindNearestNodeCoordForLatLon(coord, result);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//check if target is reachable from start on same edge
|
||||
if(currentEdgeData.forward && currentEdgeData.backward) {
|
||||
_upperbound = absDouble( w*phantomNodes.targetPhantom.ratio);
|
||||
return _upperbound/10;
|
||||
} else {
|
||||
if((startEdgeIsReversedInGraph && (phantomNodes.startPhantom.ratio > phantomNodes.targetPhantom.ratio)) || (!startEdgeIsReversedInGraph && (phantomNodes.startPhantom.ratio < phantomNodes.targetPhantom.ratio))) {
|
||||
_backwardHeap.Insert(phantomNodes.startPhantom.startNode, absDouble( w*phantomNodes.startPhantom.ratio), phantomNodes.startPhantom.startNode);
|
||||
_insertedNodes.BackInsert(phantomNodes.startPhantom.startNode);
|
||||
_forwardHeap.Insert(phantomNodes.startPhantom.targetNode, absDouble( w-w*phantomNodes.startPhantom.ratio), phantomNodes.startPhantom.targetNode);
|
||||
_insertedNodes.ForwInsert(phantomNodes.startPhantom.targetNode);
|
||||
} else {
|
||||
_upperbound = absDouble( w*phantomNodes.targetPhantom.ratio);
|
||||
return _upperbound/10;
|
||||
}
|
||||
}
|
||||
}
|
||||
inline bool FindRoutingStarts(const _Coordinate & start, const _Coordinate & target, PhantomNodes & routingStarts) {
|
||||
nodeHelpDesk->FindRoutingStarts(start, target, routingStarts);
|
||||
return true;
|
||||
}
|
||||
|
||||
//insert start and/or target node of start edge
|
||||
const EdgeData& sourceEdgeData = _graph->GetEdgeData(sourceEdgeID);
|
||||
EdgeWeight sw = sourceEdgeData.distance;
|
||||
inline bool FindPhantomNodeForCoordinate(const _Coordinate & location, PhantomNode & result) {
|
||||
return nodeHelpDesk->FindPhantomNodeForCoordinate(location, result);
|
||||
}
|
||||
|
||||
if( (sourceEdgeData.backward && !startEdgeIsReversedInGraph) || (sourceEdgeData.forward && startEdgeIsReversedInGraph) ){
|
||||
_forwardHeap.Insert(phantomNodes.startPhantom.startNode, absDouble( sw*phantomNodes.startPhantom.ratio), phantomNodes.startPhantom.startNode);
|
||||
_insertedNodes.ForwInsert(phantomNodes.startPhantom.startNode);
|
||||
}
|
||||
if( (sourceEdgeData.backward && startEdgeIsReversedInGraph) || (sourceEdgeData.forward && !startEdgeIsReversedInGraph) ) {
|
||||
_forwardHeap.Insert(phantomNodes.startPhantom.targetNode, absDouble(sw-sw*phantomNodes.startPhantom.ratio), phantomNodes.startPhantom.targetNode);
|
||||
_insertedNodes.ForwInsert(phantomNodes.startPhantom.targetNode);
|
||||
}
|
||||
inline NodeID GetNameIDForOriginDestinationNodeID(NodeID s, NodeID t) const {
|
||||
//INFO("Getting nameID for s=" << s << " and t=" << t);
|
||||
if(s == t)
|
||||
return 0;
|
||||
|
||||
//insert start and/or target node of target edge id
|
||||
const EdgeData& targetEdgeData = _graph->GetEdgeData(targetEdgeID);
|
||||
EdgeWeight tw = targetEdgeData.distance;
|
||||
|
||||
if( (targetEdgeData.backward && !targetEdgeIsReversed) || (targetEdgeData.forward && targetEdgeIsReversed) ) {
|
||||
_backwardHeap.Insert(phantomNodes.targetPhantom.targetNode, absDouble( tw*phantomNodes.targetPhantom.ratio), phantomNodes.targetPhantom.targetNode);
|
||||
_insertedNodes.BackInsert(phantomNodes.targetPhantom.targetNode);
|
||||
}
|
||||
if( (targetEdgeData.backward && targetEdgeIsReversed) || (targetEdgeData.forward && !targetEdgeIsReversed) ) {
|
||||
_backwardHeap.Insert(phantomNodes.targetPhantom.startNode, absDouble(tw-tw*phantomNodes.targetPhantom.ratio), phantomNodes.targetPhantom.startNode);
|
||||
_insertedNodes.BackInsert(phantomNodes.targetPhantom.startNode);
|
||||
}
|
||||
|
||||
while(_forwardHeap.Size() + _backwardHeap.Size() > 0) {
|
||||
if ( _forwardHeap.Size() > 0 ) {
|
||||
_RoutingStep( _forwardHeap, _backwardHeap, true, &middle, &_upperbound );
|
||||
}
|
||||
if ( _backwardHeap.Size() > 0 ) {
|
||||
_RoutingStep( _backwardHeap, _forwardHeap, false, &middle, &_upperbound );
|
||||
}
|
||||
}
|
||||
|
||||
if ( _upperbound == UINT_MAX ) {
|
||||
return _upperbound;
|
||||
}
|
||||
|
||||
NodeID pathNode = middle;
|
||||
deque< NodeID > packedPath;
|
||||
|
||||
while ( false == _insertedNodes.isForwardInserted(pathNode) ) {
|
||||
pathNode = _forwardHeap.GetData( pathNode ).parent;
|
||||
packedPath.push_front( pathNode );
|
||||
}
|
||||
|
||||
packedPath.push_back( middle );
|
||||
pathNode = middle;
|
||||
|
||||
while ( false == _insertedNodes.isBackwardInserted(pathNode) ){
|
||||
pathNode = _backwardHeap.GetData( pathNode ).parent;
|
||||
packedPath.push_back( pathNode );
|
||||
}
|
||||
|
||||
path.push_back( _PathData(packedPath[0]) );
|
||||
for(deque<NodeID>::size_type i = 0; i < packedPath.size()-1; i++) {
|
||||
_UnpackEdge(packedPath[i], packedPath[i+1], path);
|
||||
}
|
||||
|
||||
packedPath.clear();
|
||||
return _upperbound/10;
|
||||
}
|
||||
|
||||
unsigned int ComputeDistanceBetweenNodes(NodeID start, NodeID target) {
|
||||
_Heap _forwardHeap(_graph->GetNumberOfNodes());
|
||||
_Heap _backwardHeap(_graph->GetNumberOfNodes());
|
||||
NodeID middle(UINT_MAX);
|
||||
unsigned int _upperbound = UINT_MAX;
|
||||
|
||||
_forwardHeap.Insert(start, 0, start);
|
||||
_backwardHeap.Insert(target, 0, target);
|
||||
|
||||
while(_forwardHeap.Size() + _backwardHeap.Size() > 0) {
|
||||
if ( _forwardHeap.Size() > 0 ) {
|
||||
_RoutingStep( _forwardHeap, _backwardHeap, true, &middle, &_upperbound );
|
||||
}
|
||||
if ( _backwardHeap.Size() > 0 ) {
|
||||
_RoutingStep( _backwardHeap, _forwardHeap, false, &middle, &_upperbound );
|
||||
}
|
||||
}
|
||||
return _upperbound;
|
||||
}
|
||||
|
||||
unsigned int ComputeDistanceBetweenNodesWithStats(NodeID start, NodeID target, _Statistics& stats) {
|
||||
_Heap _forwardHeap(_graph->GetNumberOfNodes());
|
||||
_Heap _backwardHeap(_graph->GetNumberOfNodes());
|
||||
NodeID middle(UINT_MAX);
|
||||
unsigned int _upperbound = UINT_MAX;
|
||||
|
||||
_forwardHeap.Insert(start, 0, start);
|
||||
_backwardHeap.Insert(target, 0, target);
|
||||
stats.insertedNodes += 2;
|
||||
|
||||
while(_forwardHeap.Size() + _backwardHeap.Size() > 0) {
|
||||
if ( _forwardHeap.Size() > 0 ) {
|
||||
_RoutingStepWithStats( _forwardHeap, _backwardHeap, true, &middle, &_upperbound, stats );
|
||||
}
|
||||
if ( _backwardHeap.Size() > 0 ) {
|
||||
_RoutingStepWithStats( _backwardHeap, _forwardHeap, false, &middle, &_upperbound, stats );
|
||||
}
|
||||
}
|
||||
return _upperbound;
|
||||
}
|
||||
|
||||
inline unsigned int findNearestNodeForLatLon(const _Coordinate& coord, _Coordinate& result) const
|
||||
{
|
||||
nodeHelpDesk->findNearestNodeCoordForLatLon( coord, result );
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
inline bool FindRoutingStarts(const _Coordinate &start, const _Coordinate &target, PhantomNodes & routingStarts) {
|
||||
nodeHelpDesk->FindRoutingStarts(start, target, routingStarts);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool FindPhantomNodeForCoordinate(const _Coordinate &location, PhantomNode & result) {
|
||||
return nodeHelpDesk->FindPhantomNodeForCoordinate(location, result);
|
||||
}
|
||||
|
||||
inline NodeID GetNameIDForOriginDestinationNodeID(NodeID s, NodeID t) const {
|
||||
//INFO("Getting nameID for s=" << s << " and t=" << t);
|
||||
if(s==t)
|
||||
return 0;
|
||||
EdgeID e = _graph->FindEdge( s, t );
|
||||
if(e == UINT_MAX)
|
||||
EdgeID e = _graph->FindEdge(s, t);
|
||||
if(e == UINT_MAX)
|
||||
e = _graph->FindEdge( t, s );
|
||||
if(UINT_MAX == e) {
|
||||
if(UINT_MAX == e) {
|
||||
// INFO("edge not found for start " << s << ", target " << t)
|
||||
return 0;
|
||||
}
|
||||
assert(e != UINT_MAX);
|
||||
const EdgeData ed = _graph->GetEdgeData(e);
|
||||
return ed.middleName.nameID;
|
||||
}
|
||||
assert(e != UINT_MAX);
|
||||
const EdgeData ed = _graph->GetEdgeData(e);
|
||||
return ed.via;
|
||||
}
|
||||
|
||||
inline NodeID GetWeightForOriginDestinationNodeID(NodeID s, NodeID t) const {
|
||||
assert(s!=t);
|
||||
EdgeID e = _graph->FindEdge( s, t );
|
||||
if(e == UINT_MAX)
|
||||
inline NodeID GetWeightForOriginDestinationNodeID(NodeID s, NodeID t) const {
|
||||
assert(s!=t);
|
||||
EdgeID e = _graph->FindEdge(s, t);
|
||||
if(e == UINT_MAX)
|
||||
e = _graph->FindEdge( t, s );
|
||||
assert(e != UINT_MAX);
|
||||
const EdgeData ed = _graph->GetEdgeData(e);
|
||||
return ed.distance;
|
||||
}
|
||||
assert(e != UINT_MAX);
|
||||
const EdgeData ed = _graph->GetEdgeData(e);
|
||||
return ed.distance;
|
||||
}
|
||||
|
||||
inline std::string &GetUnescapedNameForNameID(const NodeID nameID) const {
|
||||
return (nameID >= _names->size() ? _names->at(0) : _names->at(nameID) );
|
||||
}
|
||||
inline std::string & GetUnescapedNameForNameID(const NodeID nameID) const {
|
||||
return (nameID >= _names->size() ? _names->at(0) : _names->at(nameID));
|
||||
}
|
||||
|
||||
inline std::string GetEscapedNameForOriginDestinationNodeID(NodeID s, NodeID t) const {
|
||||
NodeID nameID = GetNameIDForOriginDestinationNodeID(s, t);
|
||||
return ( GetEscapedNameForNameID(nameID) );
|
||||
}
|
||||
inline std::string GetEscapedNameForOriginDestinationNodeID(NodeID s, NodeID t) const {
|
||||
NodeID nameID = GetNameIDForOriginDestinationNodeID(s, t);
|
||||
return (GetEscapedNameForNameID(nameID));
|
||||
}
|
||||
|
||||
inline std::string GetEscapedNameForNameID(const NodeID nameID) const {
|
||||
return ( (nameID >= _names->size() || nameID == 0) ? std::string("") : HTMLEntitize(_names->at(nameID)) );
|
||||
}
|
||||
inline std::string GetEscapedNameForNameID(const NodeID nameID) const {
|
||||
return ((nameID >= _names->size() || nameID == 0) ? std::string("") : HTMLEntitize(_names->at(nameID)));
|
||||
}
|
||||
|
||||
inline short GetTypeOfEdgeForOriginDestinationNodeID(NodeID s, NodeID t) const {
|
||||
assert(s!=t);
|
||||
EdgeID e = _graph->FindEdge( s, t );
|
||||
if(e == UINT_MAX)
|
||||
inline short GetTypeOfEdgeForOriginDestinationNodeID(NodeID s, NodeID t) const {
|
||||
assert(s!=t);
|
||||
EdgeID e = _graph->FindEdge(s, t);
|
||||
if(e == UINT_MAX)
|
||||
e = _graph->FindEdge( t, s );
|
||||
assert(e != UINT_MAX);
|
||||
const EdgeData ed = _graph->GetEdgeData(e);
|
||||
return ed.type;
|
||||
}
|
||||
assert(e != UINT_MAX);
|
||||
const EdgeData ed = _graph->GetEdgeData(e);
|
||||
return ed.type;
|
||||
}
|
||||
|
||||
// inline void RegisterThread(const unsigned k, const unsigned v) {
|
||||
// nodeHelpDesk->RegisterThread(k,v);
|
||||
// }
|
||||
private:
|
||||
inline void _RoutingStep(HeapPtr & _forwardHeap, HeapPtr & _backwardHeap, const bool & forwardDirection, NodeID *middle, unsigned int *_upperbound) {
|
||||
const NodeID node = _forwardHeap->DeleteMin();
|
||||
const unsigned int distance = _forwardHeap->GetKey(node);
|
||||
if(_backwardHeap->WasInserted(node)){
|
||||
const unsigned int newDistance = _backwardHeap->GetKey(node) + distance;
|
||||
if(newDistance < *_upperbound){
|
||||
*middle = node;
|
||||
*_upperbound = newDistance;
|
||||
}
|
||||
}
|
||||
|
||||
inline void _RoutingStep(_Heap& _forwardHeap, _Heap &_backwardHeap, const bool& forwardDirection, NodeID * middle, unsigned int * _upperbound) {
|
||||
const NodeID node = _forwardHeap.DeleteMin();
|
||||
const unsigned int distance = _forwardHeap.GetKey( node );
|
||||
if ( _backwardHeap.WasInserted( node ) ) {
|
||||
const unsigned int newDistance = _backwardHeap.GetKey( node ) + distance;
|
||||
if ( newDistance < *_upperbound ) {
|
||||
*middle = node;
|
||||
*_upperbound = newDistance;
|
||||
}
|
||||
}
|
||||
if ( distance > *_upperbound ) {
|
||||
_forwardHeap.DeleteAll();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
for ( typename GraphT::EdgeIterator edge = _graph->BeginEdges( node ); edge < _graph->EndEdges(node); edge++ ) {
|
||||
if(distance > *_upperbound){
|
||||
_forwardHeap->DeleteAll();
|
||||
return;
|
||||
}
|
||||
/* for ( typename GraphT::EdgeIterator edge = _graph->BeginEdges( node ); edge < _graph->EndEdges(node); edge++ ) {
|
||||
const NodeID to = _graph->GetTarget(edge);
|
||||
const EdgeWeight edgeWeight = _graph->GetEdgeData(edge).distance;
|
||||
|
||||
@@ -354,57 +278,57 @@ private:
|
||||
|
||||
//Stalling
|
||||
bool backwardDirectionFlag = (!forwardDirection) ? _graph->GetEdgeData(edge).forward : _graph->GetEdgeData(edge).backward;
|
||||
if(_forwardHeap.WasInserted( to )) {
|
||||
if(_forwardHeap->WasInserted( to )) {
|
||||
if(backwardDirectionFlag) {
|
||||
if(_forwardHeap.GetKey( to ) + edgeWeight < distance) {
|
||||
if(_forwardHeap->GetKey( to ) + edgeWeight < distance) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for ( typename GraphT::EdgeIterator edge = _graph->BeginEdges( node ); edge < _graph->EndEdges(node); edge++ ) {
|
||||
*/
|
||||
for ( typename GraphT::EdgeIterator edge = _graph->BeginEdges( node ); edge < _graph->EndEdges(node); edge++ ) {
|
||||
const NodeID to = _graph->GetTarget(edge);
|
||||
const EdgeWeight edgeWeight = _graph->GetEdgeData(edge).distance;
|
||||
|
||||
assert( edgeWeight > 0 );
|
||||
const int toDistance = distance + edgeWeight;
|
||||
|
||||
assert(toDistance > 0);
|
||||
|
||||
bool forwardDirectionFlag = (forwardDirection ? _graph->GetEdgeData(edge).forward : _graph->GetEdgeData(edge).backward );
|
||||
if(forwardDirectionFlag) {
|
||||
//New Node discovered -> Add to Heap + Node Info Storage
|
||||
if ( !_forwardHeap.WasInserted( to ) ) {
|
||||
_forwardHeap.Insert( to, toDistance, node );
|
||||
if ( !_forwardHeap->WasInserted( to ) ) {
|
||||
_forwardHeap->Insert( to, toDistance, node );
|
||||
}
|
||||
//Found a shorter Path -> Update distance
|
||||
else if ( toDistance < _forwardHeap.GetKey( to ) ) {
|
||||
_forwardHeap.GetData( to ).parent = node;
|
||||
_forwardHeap.DecreaseKey( to, toDistance );
|
||||
else if ( toDistance < _forwardHeap->GetKey( to ) ) {
|
||||
_forwardHeap->GetData( to ).parent = node;
|
||||
_forwardHeap->DecreaseKey( to, toDistance );
|
||||
//new parent
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void _RoutingStepWithStats( _Heap& _forwardHeap, _Heap &_backwardHeap, const bool& forwardDirection, NodeID * middle, unsigned int * _upperbound, _Statistics& stats) {
|
||||
const NodeID node = _forwardHeap.DeleteMin();
|
||||
stats.deleteMins++;
|
||||
const unsigned int distance = _forwardHeap.GetKey( node );
|
||||
if ( _backwardHeap.WasInserted( node ) ) {
|
||||
const unsigned int newDistance = _backwardHeap.GetKey( node ) + distance;
|
||||
if ( newDistance < *_upperbound ) {
|
||||
*middle = node;
|
||||
*_upperbound = newDistance;
|
||||
}
|
||||
}
|
||||
if ( distance > *_upperbound ) {
|
||||
stats.meetingNodes++;
|
||||
_forwardHeap.DeleteAll();
|
||||
return;
|
||||
}
|
||||
inline void _RoutingStepWithStats(HeapPtr & _forwardHeap, HeapPtr & _backwardHeap, const bool & forwardDirection, NodeID *middle, unsigned int *_upperbound, _Statistics & stats) {
|
||||
const NodeID node = _forwardHeap->DeleteMin();
|
||||
stats.deleteMins++;
|
||||
const unsigned int distance = _forwardHeap->GetKey(node);
|
||||
if(_backwardHeap->WasInserted(node)){
|
||||
const unsigned int newDistance = _backwardHeap->GetKey(node) + distance;
|
||||
if(newDistance < *_upperbound){
|
||||
*middle = node;
|
||||
*_upperbound = newDistance;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for ( typename GraphT::EdgeIterator edge = _graph->BeginEdges( node ); edge < _graph->EndEdges(node); edge++ ) {
|
||||
if(distance > *_upperbound) {
|
||||
stats.meetingNodes++;
|
||||
_forwardHeap->DeleteAll();
|
||||
return;
|
||||
}
|
||||
for ( typename GraphT::EdgeIterator edge = _graph->BeginEdges( node ); edge < _graph->EndEdges(node); edge++ ) {
|
||||
const EdgeData& ed = _graph->GetEdgeData(edge);
|
||||
const NodeID to = _graph->GetTarget(edge);
|
||||
const EdgeWeight edgeWeight = ed.distance;
|
||||
@@ -413,9 +337,9 @@ private:
|
||||
const int toDistance = distance + edgeWeight;
|
||||
|
||||
//Stalling
|
||||
if(_forwardHeap.WasInserted( to )) {
|
||||
if(_forwardHeap->WasInserted( to )) {
|
||||
if(!forwardDirection ? ed.forward : ed.backward) {
|
||||
if(_forwardHeap.GetKey( to ) + edgeWeight < distance) {
|
||||
if(_forwardHeap->GetKey( to ) + edgeWeight < distance) {
|
||||
stats.stalledNodes++;
|
||||
return;
|
||||
}
|
||||
@@ -424,57 +348,62 @@ private:
|
||||
|
||||
if(forwardDirection ? ed.forward : ed.backward ) {
|
||||
//New Node discovered -> Add to Heap + Node Info Storage
|
||||
if ( !_forwardHeap.WasInserted( to ) ) {
|
||||
_forwardHeap.Insert( to, toDistance, node );
|
||||
if ( !_forwardHeap->WasInserted( to ) ) {
|
||||
_forwardHeap->Insert( to, toDistance, node );
|
||||
stats.insertedNodes++;
|
||||
}
|
||||
//Found a shorter Path -> Update distance
|
||||
else if ( toDistance < _forwardHeap.GetKey( to ) ) {
|
||||
_forwardHeap.GetData( to ).parent = node;
|
||||
_forwardHeap.DecreaseKey( to, toDistance );
|
||||
else if ( toDistance < _forwardHeap->GetKey( to ) ) {
|
||||
_forwardHeap->GetData( to ).parent = node;
|
||||
_forwardHeap->DecreaseKey( to, toDistance );
|
||||
stats.decreasedNodes++;
|
||||
//new parent
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline bool _UnpackEdge( const NodeID source, const NodeID target, std::vector< _PathData >& path ) {
|
||||
assert(source != target);
|
||||
//find edge first.
|
||||
bool forward = true;
|
||||
typename GraphT::EdgeIterator smallestEdge = SPECIAL_EDGEID;
|
||||
EdgeWeight smallestWeight = UINT_MAX;
|
||||
for(typename GraphT::EdgeIterator eit = _graph->BeginEdges(source); eit < _graph->EndEdges(source); eit++) {
|
||||
const EdgeWeight weight = _graph->GetEdgeData(eit).distance;
|
||||
if(_graph->GetTarget(eit) == target && weight < smallestWeight && _graph->GetEdgeData(eit).forward) {
|
||||
smallestEdge = eit; smallestWeight = weight;
|
||||
}
|
||||
}
|
||||
if(smallestEdge == SPECIAL_EDGEID) {
|
||||
for(typename GraphT::EdgeIterator eit = _graph->BeginEdges(target); eit < _graph->EndEdges(target); eit++) {
|
||||
const EdgeWeight weight = _graph->GetEdgeData(eit).distance;
|
||||
if(_graph->GetTarget(eit) == source && weight < smallestWeight && _graph->GetEdgeData(eit).backward) {
|
||||
smallestEdge = eit; smallestWeight = weight;
|
||||
forward = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
inline bool _UnpackEdge(const NodeID source, const NodeID target, std::vector<_PathData> & path) {
|
||||
assert(source != target);
|
||||
//find edge first.
|
||||
typename GraphT::EdgeIterator smallestEdge = SPECIAL_EDGEID;
|
||||
EdgeWeight smallestWeight = UINT_MAX;
|
||||
for(typename GraphT::EdgeIterator eit = _graph->BeginEdges(source);eit < _graph->EndEdges(source);eit++){
|
||||
const EdgeWeight weight = _graph->GetEdgeData(eit).distance;
|
||||
if(_graph->GetTarget(eit) == target && weight < smallestWeight && _graph->GetEdgeData(eit).forward){
|
||||
smallestEdge = eit;
|
||||
smallestWeight = weight;
|
||||
}
|
||||
}
|
||||
|
||||
assert(smallestWeight != SPECIAL_EDGEID); //no edge found. This should not happen at all!
|
||||
if(smallestEdge == SPECIAL_EDGEID){
|
||||
for(typename GraphT::EdgeIterator eit = _graph->BeginEdges(target);eit < _graph->EndEdges(target);eit++){
|
||||
const EdgeWeight weight = _graph->GetEdgeData(eit).distance;
|
||||
if(_graph->GetTarget(eit) == source && weight < smallestWeight && _graph->GetEdgeData(eit).backward){
|
||||
smallestEdge = eit;
|
||||
smallestWeight = weight;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
assert(smallestWeight != SPECIAL_EDGEID);
|
||||
|
||||
const EdgeData& ed = _graph->GetEdgeData(smallestEdge);
|
||||
// INFO( (ed.shortcut ? "SHRT: " : "ORIG: ") << ed.distance << "," << ed.via);
|
||||
if(ed.shortcut) {//unpack
|
||||
const NodeID middle = ed.middleName.middle;
|
||||
const NodeID middle = ed.via;
|
||||
_UnpackEdge(source, middle, path);
|
||||
_UnpackEdge(middle, target, path);
|
||||
return false;
|
||||
} else {
|
||||
assert(!ed.shortcut);
|
||||
path.push_back(_PathData(target) );
|
||||
path.push_back(_PathData(ed.via) );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
template<class EdgeData, class GraphT> HeapPtr SearchEngine<EdgeData, GraphT>::_forwardHeap;
|
||||
template<class EdgeData, class GraphT> HeapPtr SearchEngine<EdgeData, GraphT>::_backwardHeap;
|
||||
|
||||
#endif /* SEARCHENGINE_H_ */
|
||||
|
||||
@@ -49,7 +49,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
StaticGraph( int nodes, std::vector< InputEdge > &graph ) {
|
||||
StaticGraph( const int nodes, std::vector< InputEdge > &graph ) {
|
||||
#ifdef _GLIBCXX_PARALLEL
|
||||
__gnu_parallel::sort( graph.begin(), graph.end() );
|
||||
#else
|
||||
@@ -62,9 +62,8 @@ public:
|
||||
EdgeIterator position = 0;
|
||||
for ( NodeIterator node = 0; node <= _numNodes; ++node ) {
|
||||
EdgeIterator lastEdge = edge;
|
||||
while ( edge < _numEdges && graph[edge].source == node ) {
|
||||
while ( edge < _numEdges && graph[edge].source == node )
|
||||
++edge;
|
||||
}
|
||||
_nodes[node].firstEdge = position; //=edge
|
||||
position += edge - lastEdge; //remove
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user