First working edge based version. Still missing: GPX export; Via Points;

origin,destination on same edge, descriptions
This commit is contained in:
DennisOSRM 2011-11-14 19:36:31 +01:00
parent 34e4ead885
commit 97afa231ca
24 changed files with 512 additions and 1248 deletions

View File

@ -62,10 +62,6 @@ private:
delete _heapForward; delete _heapForward;
} }
}; };
union _MiddleName {
NodeID nameID;
NodeID middle;
};
public: public:
@ -73,12 +69,13 @@ public:
NodeID source; NodeID source;
NodeID target; NodeID target;
struct EdgeData { struct EdgeData {
int distance : 30; NodeID via;
bool shortcut : 1; unsigned nameID1;
bool forward : 1; unsigned nameID2;
bool backward : 1; int distance;
short type:7; bool shortcut;
_MiddleName middleName; bool forward;
bool backward;
} data; } data;
//sorts by source and other attributes //sorts by source and other attributes
@ -95,7 +92,10 @@ public:
} }
bool operator== ( const Edge& right ) const { bool operator== ( const Edge& right ) const {
return ( source == right.source && target == right.target && data.distance == right.data.distance && data.shortcut == right.data.shortcut && data.forward == right.data.forward && data.backward == right.data.backward && data.middleName.middle == right.data.middleName.middle ); return ( source == right.source && target == right.target && data.distance == right.data.distance &&
data.shortcut == right.data.shortcut && data.forward == right.data.forward && data.backward == right.data.backward
&& data.via == right.data.via && data.nameID1 == right.data.nameID1 && data.nameID2 == right.data.nameID2
);
} }
}; };

View File

@ -117,6 +117,7 @@ public:
edge.data.shortcut = false; edge.data.shortcut = false;
edge.data.nameID1 = i->nameID1(); edge.data.nameID1 = i->nameID1();
edge.data.nameID2 = i->nameID2(); edge.data.nameID2 = i->nameID2();
edge.data.via = i->via();
edge.data.turnType = i->turnType(); edge.data.turnType = i->turnType();
edge.data.forward = i->isForward(); edge.data.forward = i->isForward();
edge.data.backward = i->isBackward(); edge.data.backward = i->isBackward();
@ -430,12 +431,6 @@ private:
return edgeQuotionFactor * ((( double ) stats.edgesAdded ) / stats.edgesDeleted ) + originalQuotientFactor * ((( double ) stats.originalEdgesAdded ) / stats.originalEdgesDeleted ) + depthFactor * nodeData->depth; return edgeQuotionFactor * ((( double ) stats.edgesAdded ) / stats.edgesDeleted ) + originalQuotientFactor * ((( double ) stats.originalEdgesAdded ) / stats.originalEdgesDeleted ) + depthFactor * nodeData->depth;
} }
/*
8 * numAdded / numDeleted + 4 * numOriginalAdded / numOriginalDeleted + 2 * Tiefe
Kante einfüge = numAdded += 2 && numOriginalAdded += 2 * numOriginal
Kante löschen = numDeleted += 1 && numOriginalAdded += numOriginal
*/
template< class Edge > template< class Edge >
bool _CheckCH() bool _CheckCH()
{ {

View File

@ -32,12 +32,14 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include <google/sparse_hash_map> #include <google/sparse_hash_map>
#include <google/sparsetable> #include <google/sparsetable>
template< typename NodeID, typename Key, bool initialize = true > template< typename NodeID, typename Key >
class ArrayStorage { class ArrayStorage {
public: public:
ArrayStorage( size_t size ) ArrayStorage( size_t size ) : positions( new Key[size] ) {
: positions( new Key[size] ) { if(initialize) { memset(positions, 0, size*sizeof(Key));} } memset(positions, 0, size*sizeof(Key));
INFO("initializing q for " << size << " elements");
}
~ArrayStorage() { ~ArrayStorage() {
delete[] positions; delete[] positions;
@ -123,10 +125,6 @@ struct _SimpleHeapData {
_SimpleHeapData( NodeID p ) : parent(p) { } _SimpleHeapData( NodeID p ) : parent(p) { }
}; };
//struct _NullHeapData {
// _NullHeapData(NodeID p) {}
//};
template < typename NodeID, typename Key, typename Weight, typename Data, typename IndexStorage = ArrayStorage<NodeID, NodeID> > template < typename NodeID, typename Key, typename Weight, typename Data, typename IndexStorage = ArrayStorage<NodeID, NodeID> >
class BinaryHeap { class BinaryHeap {
private: private:
@ -144,7 +142,7 @@ public:
void Clear() { void Clear() {
heap.resize( 1 ); heap.resize( 1 );
insertedNodes.clear(); insertedNodes.clear();
heap[0].weight = (std::numeric_limits< Weight >::min)(); heap[0].weight = std::numeric_limits< Weight >::min();
nodeIndex.Clear(); nodeIndex.Clear();
} }
@ -215,7 +213,7 @@ public:
assert( UINT_MAX != node ); assert( UINT_MAX != node );
const Key index = nodeIndex[node]; const Key index = nodeIndex[node];
Key key = insertedNodes[index].key; Key key = insertedNodes[index].key;
assert ( key != 0 ); assert ( key >= 0 );
insertedNodes[index].weight = weight; insertedNodes[index].weight = weight;
heap[key].weight = weight; heap[key].weight = weight;

View File

@ -81,9 +81,7 @@ class DynamicGraph {
} }
} }
~DynamicGraph() ~DynamicGraph(){ }
{
}
unsigned GetNumberOfNodes() const unsigned GetNumberOfNodes() const
{ {

View File

@ -22,10 +22,9 @@ or see http://www.gnu.org/licenses/agpl.txt.
#define GRIDEDGE_H_ #define GRIDEDGE_H_
struct _GridEdge { struct _GridEdge {
_GridEdge(NodeID s, NodeID t, _Coordinate sc, _Coordinate tc) : start(s), target(t), startCoord(sc), targetCoord(tc) {} _GridEdge(NodeID n, _Coordinate sc, _Coordinate tc) : edgeBasedNode(n), startCoord(sc), targetCoord(tc) {}
_GridEdge() : start(UINT_MAX), target(UINT_MAX) {} _GridEdge() : edgeBasedNode(UINT_MAX) {}
NodeID start; NodeID edgeBasedNode;
NodeID target;
_Coordinate startCoord; _Coordinate startCoord;
_Coordinate targetCoord; _Coordinate targetCoord;
}; };
@ -37,14 +36,10 @@ struct GridEntry {
unsigned fileIndex; unsigned fileIndex;
unsigned ramIndex; unsigned ramIndex;
bool operator< ( const GridEntry& right ) const { bool operator< ( const GridEntry& right ) const {
if(right.edge.start != edge.start) return (edge.edgeBasedNode < right.edge.edgeBasedNode);
return right.edge.start < edge.start;
if(right.edge.target != edge.target)
return right.edge.target < edge.target;
return false;
} }
bool operator==( const GridEntry& right ) const { bool operator==( const GridEntry& right ) const {
return right.edge.start == edge.start && right.edge.target == edge.target; return right.edge.edgeBasedNode == edge.edgeBasedNode;
} }
}; };

View File

@ -23,10 +23,10 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include <cassert> #include <cassert>
class Edge { class NodeBasedEdge {
public: public:
bool operator< (const Edge& e) const { bool operator< (const NodeBasedEdge& e) const {
if (source() == e.source()) { if (source() == e.source()) {
if (target() == e.target()) { if (target() == e.target()) {
if (weight() == e.weight()) { if (weight() == e.weight()) {
@ -41,10 +41,10 @@ public:
} }
/** Default constructor. target and weight are set to 0.*/ /** 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. _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); } _source(s), _target(t), _name(n), _weight(w), forward(f), backward(b), _type(ty) { assert(ty >= 0); }
NodeID target() const {return _target; } NodeID target() const {return _target; }
@ -59,21 +59,79 @@ public:
NodeID _source; NodeID _source;
NodeID _target; NodeID _target;
NodeID _name:31; NodeID _name;
EdgeWeight _weight:31; EdgeWeight _weight;
bool forward:1; bool forward;
bool backward:1; bool backward;
short _type; 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: public:
EdgeWeight distance; EdgeWeight distance;
bool forward; bool forward;
bool backward; bool backward;
}; };
typedef Edge ImportEdge; typedef NodeBasedEdge ImportEdge;
#endif // EDGE_H #endif // EDGE_H

View File

@ -37,6 +37,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
#endif #endif
#include <boost/thread.hpp> #include <boost/thread.hpp>
#include <boost/foreach.hpp>
#include <google/dense_hash_map> #include <google/dense_hash_map>
#include "ExtractorStructs.h" #include "ExtractorStructs.h"
@ -148,16 +149,6 @@ static void GetListOfIndexesForEdgeAndGridSize(_Coordinate& start, _Coordinate&
template<bool WriteAccess = false> template<bool WriteAccess = false>
class NNGrid { class NNGrid {
private:
struct DiskEdge {
NodeID start;
NodeID target;
int slat;
int slon;
int tlat;
int tlon;
};
public: public:
NNGrid() : cellCache(500), fileCache(500) { NNGrid() : cellCache(500), fileCache(500) {
ramIndexTable.resize((1024*1024), UINT_MAX); 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) { 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); iif = std::string(_i);
ramIndexTable.resize((1024*1024), UINT_MAX); ramIndexTable.resize((1024*1024), UINT_MAX);
ramInFile.open(rif, std::ios::in | std::ios::binary); ramInFile.open(rif, std::ios::in | std::ios::binary);
@ -183,7 +177,7 @@ public:
void OpenIndexFiles() { void OpenIndexFiles() {
assert(ramInFile.is_open()); assert(ramInFile.is_open());
for(int i = 0; i < 1024*1024; i++) { for(int i = 0; i < 1024*1024; ++i) {
unsigned temp; unsigned temp;
ramInFile.read((char*)&temp, sizeof(unsigned)); ramInFile.read((char*)&temp, sizeof(unsigned));
ramIndexTable[i] = temp; ramIndexTable[i] = temp;
@ -194,19 +188,16 @@ public:
template<typename EdgeT, typename NodeInfoT> template<typename EdgeT, typename NodeInfoT>
void ConstructGrid(std::vector<EdgeT> & edgeList, vector<NodeInfoT> * int2ExtNodeMap, char * ramIndexOut, char * fileIndexOut) { void ConstructGrid(std::vector<EdgeT> & edgeList, vector<NodeInfoT> * int2ExtNodeMap, char * ramIndexOut, char * fileIndexOut) {
Percent p(edgeList.size()); Percent p(edgeList.size());
for(NodeID i = 0; i < edgeList.size(); i++) { for(NodeID i = 0; i < edgeList.size(); ++i) {
p.printIncrement(); p.printIncrement();
if( edgeList[i].isLocatable() == false ) EdgeT & edge = edgeList[i];
continue;
EdgeT edge = edgeList[i];
int slat = 100000*lat2y(static_cast<double>(int2ExtNodeMap->at(edge.source()).lat)/100000.); int slat = 100000*lat2y(edge.lat1/100000.);
int slon = int2ExtNodeMap->at(edge.source()).lon; int slon = edge.lon1;
int tlat = 100000*lat2y(static_cast<double>(int2ExtNodeMap->at(edge.target()).lat)/100000.); int tlat = 100000*lat2y(edge.lat2/100000.);
int tlon = int2ExtNodeMap->at(edge.target()).lon; int tlon = edge.lon2;
AddEdge( _GridEdge( AddEdge( _GridEdge(
edgeList[i].source(), edge.id,
edgeList[i].target(),
_Coordinate(slat, slon), _Coordinate(slat, slon),
_Coordinate(tlat, tlon) ) _Coordinate(tlat, tlon) )
); );
@ -225,7 +216,7 @@ public:
unsigned maxNumberOfRAMCellElements = 0; unsigned maxNumberOfRAMCellElements = 0;
cout << "writing data ..." << flush; cout << "writing data ..." << flush;
p.reinit(entries->size()); 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(); p.printIncrement();
if(vt->ramIndex != indexInRamTable) { if(vt->ramIndex != indexInRamTable) {
unsigned numberOfBytesInCell = FillCell(entriesInFileWithRAMSameIndex, lastPositionInIndexFile); unsigned numberOfBytesInCell = FillCell(entriesInFileWithRAMSameIndex, lastPositionInIndexFile);
@ -247,7 +238,7 @@ public:
assert(entriesInFileWithRAMSameIndex.size() == 0); 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) { if(ramIndexTable[i] != UINT_MAX) {
numberOfUsedCells--; numberOfUsedCells--;
} }
@ -259,17 +250,17 @@ public:
//Serialize RAM Index //Serialize RAM Index
ofstream ramFile(ramIndexOut, std::ios::out | std::ios::binary | std::ios::trunc); ofstream ramFile(ramIndexOut, std::ios::out | std::ios::binary | std::ios::trunc);
//write 4 MB of index Table in RAM //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) ); ramFile.write((char *)&ramIndexTable[i], sizeof(unsigned) );
//close ram index file //close ram index file
ramFile.close(); 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); _Coordinate startCoord(100000*(lat2y(static_cast<double>(coord.lat)/100000.)), coord.lon);
/** search for point on edge next to source */ /** search for point on edge next to source */
unsigned fileIndex = GetFileIndexForLatLon(startCoord.lat, startCoord.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 j = -32768; j < (32768+1); j+=32768) {
for(int i = -1; i < 2; i++){ for(int i = -1; i < 2; i++){
@ -277,13 +268,12 @@ public:
} }
} }
_Coordinate tmp; _Coordinate tmp;
double dist = (numeric_limits<double>::max)(); 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 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) { if(tmpDist < dist) {
nodesOfEdge.startID = it->start; nodesOfEdge.edgeBasedNode = candidate.edgeBasedNode;
nodesOfEdge.destID = it->target;
nodesOfEdge.ratio = r; nodesOfEdge.ratio = r;
dist = tmpDist; dist = tmpDist;
nodesOfEdge.projectedPoint.lat = round(100000*(y2lat(static_cast<double>(tmp.lat)/100000.))); nodesOfEdge.projectedPoint.lat = round(100000*(y2lat(static_cast<double>(tmp.lat)/100000.)));
@ -297,11 +287,12 @@ public:
} }
bool FindPhantomNodeForCoordinate( const _Coordinate & location, PhantomNode & resultNode) { bool FindPhantomNodeForCoordinate( const _Coordinate & location, PhantomNode & resultNode) {
INFO("FindPhantomNodeForCoordinate");
bool foundNode = false; bool foundNode = false;
_Coordinate startCoord(100000*(lat2y(static_cast<double>(location.lat)/100000.)), location.lon); _Coordinate startCoord(100000*(lat2y(static_cast<double>(location.lat)/100000.)), location.lon);
/** search for point on edge close to source */ /** search for point on edge close to source */
unsigned fileIndex = GetFileIndexForLatLon(startCoord.lat, startCoord.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 j = -32768; j < (32768+1); j+=32768) {
for(int i = -1; i < 2; i++){ for(int i = -1; i < 2; i++){
@ -311,13 +302,16 @@ public:
_Coordinate tmp; _Coordinate tmp;
double dist = (numeric_limits<double>::max)(); 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 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) { if(tmpDist < dist) {
// std::cout << "[debug] start distance " << (it - candidates.begin()) << " " << tmpDist << std::endl; resultNode.isBidirected = false;
resultNode.startNode = it->start; resultNode.edgeBasedNode = candidate.edgeBasedNode;
resultNode.targetNode = it->target;
resultNode.ratio = r; resultNode.ratio = r;
dist = tmpDist; dist = tmpDist;
resultNode.location.lat = round(100000*(y2lat(static_cast<double>(tmp.lat)/100000.))); resultNode.location.lat = round(100000*(y2lat(static_cast<double>(tmp.lat)/100000.)));
@ -334,9 +328,9 @@ public:
FindPhantomNodeForCoordinate( target, routingStarts.targetPhantom) ); 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); 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 j = -32768; j < (32768+1); j+=32768) {
for(int i = -1; i < 2; i++) { for(int i = -1; i < 2; i++) {
GetContentsOfFileBucket(fileIndex+i+j, candidates); GetContentsOfFileBucket(fileIndex+i+j, candidates);
@ -344,9 +338,9 @@ public:
} }
_Coordinate tmp; _Coordinate tmp;
double dist = (numeric_limits<double>::max)(); 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 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) { if(tmpDist < dist) {
dist = tmpDist; dist = tmpDist;
outputCoordinate = tmp; outputCoordinate = tmp;
@ -359,7 +353,7 @@ public:
_Coordinate startCoord(100000*(lat2y(static_cast<double>(inputCoordinate.lat)/100000.)), inputCoordinate.lon); _Coordinate startCoord(100000*(lat2y(static_cast<double>(inputCoordinate.lat)/100000.)), inputCoordinate.lon);
unsigned fileIndex = GetFileIndexForLatLon(startCoord.lat, startCoord.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 j = -32768; j < (32768+1); j+=32768) {
for(int i = -1; i < 2; i++) { for(int i = -1; i < 2; i++) {
GetContentsOfFileBucket(fileIndex+i+j, candidates); GetContentsOfFileBucket(fileIndex+i+j, candidates);
@ -367,9 +361,9 @@ public:
} }
_Coordinate tmp; _Coordinate tmp;
double dist = (numeric_limits<double>::max)(); 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 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) { if(tmpDist < dist) {
dist = tmpDist; dist = tmpDist;
outputCoordinate.lat = round(100000*(y2lat(static_cast<double>(tmp.lat)/100000.))); outputCoordinate.lat = round(100000*(y2lat(static_cast<double>(tmp.lat)/100000.)));
@ -381,8 +375,7 @@ public:
private: private:
unsigned FillCell(std::vector<GridEntry>& entriesWithSameRAMIndex, unsigned fileOffset ) unsigned FillCell(std::vector<GridEntry>& entriesWithSameRAMIndex, unsigned fileOffset ) {
{
vector<char> * tmpBuffer = new vector<char>(); vector<char> * tmpBuffer = new vector<char>();
tmpBuffer->resize(32*32*4096,0); tmpBuffer->resize(32*32*4096,0);
unsigned indexIntoTmpBuffer = 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); 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) 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 counter = 0;
unsigned max = UINT_MAX; unsigned max = UINT_MAX;
@ -482,44 +474,12 @@ private:
} }
sort( vectorWithSameFileIndex.begin(), vectorWithSameFileIndex.end() ); sort( vectorWithSameFileIndex.begin(), vectorWithSameFileIndex.end() );
std::vector<GridEntry>::const_iterator newEnd = unique(vectorWithSameFileIndex.begin(), vectorWithSameFileIndex.end()); vectorWithSameFileIndex.erase(unique(vectorWithSameFileIndex.begin(), vectorWithSameFileIndex.end()), vectorWithSameFileIndex.end());
for(std::vector<GridEntry>::const_iterator et = vectorWithSameFileIndex.begin(); et != newEnd; et++) BOOST_FOREACH(GridEntry entry, vectorWithSameFileIndex) {
{ char * data = (char *)&(entry.edge);
char * start = (char *)&et->edge.start; for(unsigned i = 0; i < sizeof(_GridEdge); ++i) {
for(unsigned i = 0; i < sizeof(NodeID); i++) tmpBuffer->at(index+counter) = data[i];
{ ++counter;
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++;
} }
} }
char * umax = (char *) &max; char * umax = (char *) &max;
@ -531,7 +491,7 @@ private:
return counter; 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 ramIndex = GetRAMIndexFromFileIndex(fileIndex);
unsigned startIndexInFile = ramIndexTable[ramIndex]; unsigned startIndexInFile = ramIndexTable[ramIndex];
if(startIndexInFile == UINT_MAX) { if(startIndexInFile == UINT_MAX) {
@ -569,19 +529,12 @@ private:
std::ifstream localStream(iif.c_str(), std::ios::in | std::ios::binary); std::ifstream localStream(iif.c_str(), std::ios::in | std::ios::binary);
localStream.seekg(position); localStream.seekg(position);
DiskEdge diskEdge; _GridEdge gridEdge;
do { do {
localStream.read((char *)&(diskEdge), sizeof(DiskEdge)); localStream.read((char *)&(gridEdge), sizeof(_GridEdge));
if(localStream.eof() || diskEdge.start == UINT_MAX) if(localStream.eof() || gridEdge.edgeBasedNode == UINT_MAX)
break; break;
result.push_back(gridEdge);
_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);
} while(true); } while(true);
localStream.close(); localStream.close();
@ -590,7 +543,7 @@ private:
void AddEdge(_GridEdge edge) { void AddEdge(_GridEdge edge) {
std::vector<std::pair<unsigned, unsigned> > indexList; std::vector<std::pair<unsigned, unsigned> > indexList;
GetListOfIndexesForEdgeAndGridSize(edge.startCoord, edge.targetCoord, 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)); entries->push_back(GridEntry(edge, indexList[i].first, indexList[i].second));
} }
} }

View File

@ -23,7 +23,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include <cassert> #include <cassert>
#include <cstddef> #include <cstddef>
#include <limits> #include <climits>
#include "../typedefs.h" #include "../typedefs.h"
@ -33,7 +33,7 @@ struct NodeCoords {
typedef int value_type; //type of lat,lons typedef int value_type; //type of lat,lons
NodeCoords(int _lat, int _lon, NodeT _id) : lat(_lat), lon(_lon), id(_id) {} 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 lat;
int lon; int lon;
NodeT id; NodeT id;

View File

@ -31,27 +31,30 @@ or see http://www.gnu.org/licenses/agpl.txt.
class NodeInformationHelpDesk{ class NodeInformationHelpDesk{
public: public:
NodeInformationHelpDesk(const char* ramIndexInput, const char* fileIndexInput) { NodeInformationHelpDesk(const char* ramIndexInput, const char* fileIndexInput, unsigned _numberOfNodes) : numberOfNodes(_numberOfNodes) {
readOnlyGrid = new ReadOnlyGrid(ramIndexInput,fileIndexInput); readOnlyGrid = new ReadOnlyGrid(ramIndexInput,fileIndexInput);
int2ExtNodeMap = new vector<_Coordinate>(); int2ExtNodeMap = new vector<_Coordinate>();
numberOfNodes = 0; int2ExtNodeMap->reserve(numberOfNodes);
assert(0 == int2ExtNodeMap->size());
} }
~NodeInformationHelpDesk() { ~NodeInformationHelpDesk() {
delete int2ExtNodeMap; delete int2ExtNodeMap;
delete readOnlyGrid; delete readOnlyGrid;
} }
void initNNGrid(ifstream& in) { void initNNGrid(ifstream& in) {
while(!in.eof()) { while(!in.eof()) {
NodeInfo b; NodeInfo b;
in.read((char *)&b, sizeof(b)); in.read((char *)&b, sizeof(b));
int2ExtNodeMap->push_back(_Coordinate(b.lat, b.lon)); int2ExtNodeMap->push_back(_Coordinate(b.lat, b.lon));
numberOfNodes++;
} }
in.close(); in.close();
readOnlyGrid->OpenIndexFiles(); 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; } inline int getLongitudeOfNode(const NodeID node) const { return int2ExtNodeMap->at(node).lon; }
@ -59,7 +62,7 @@ public:
NodeID getNumberOfNodes2() const { return int2ExtNodeMap->size(); } NodeID getNumberOfNodes2() const { return int2ExtNodeMap->size(); }
inline void FindNearestNodeCoordForLatLon(const _Coordinate& coord, _Coordinate& result) { inline void FindNearestNodeCoordForLatLon(const _Coordinate& coord, _Coordinate& result) {
readOnlyGrid->FindNearestNodeInGraph(coord, result); readOnlyGrid->FindNearestCoordinateOnEdgeInNodeBasedGraph(coord, result);
} }
bool FindPhantomNodeForCoordinate( const _Coordinate & location, PhantomNode & resultNode) { bool FindPhantomNodeForCoordinate( const _Coordinate & location, PhantomNode & resultNode) {
return readOnlyGrid->FindPhantomNodeForCoordinate(location, resultNode); return readOnlyGrid->FindPhantomNodeForCoordinate(location, resultNode);
@ -71,7 +74,7 @@ public:
} }
inline bool GetStartAndDestNodesOfEdge(const _Coordinate& coord, NodesOfEdge& nodesOfEdge) { 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){ inline void FindNearestPointOnEdge(const _Coordinate & input, _Coordinate& output){

View File

@ -62,7 +62,7 @@ class PBFParser : public BaseParser<_Node, _RawRestrictionContainer, _Way> {
public: public:
PBFParser(const char * fileName) 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; GOOGLE_PROTOBUF_VERIFY_VERSION;
input.open(fileName, std::ios::in | std::ios::binary); input.open(fileName, std::ios::in | std::ios::binary);
@ -525,7 +525,7 @@ private:
std::fstream input; std::fstream input;
/* ThreadData Queue */ /* ThreadData Queue */
concurrent_queue < _ThreadData* >* threadDataQueue; ConcurrentQueue < _ThreadData* >* threadDataQueue;
}; };
#endif /* PBFPARSER_H_ */ #endif /* PBFPARSER_H_ */

View File

@ -24,15 +24,13 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "ExtractorStructs.h" #include "ExtractorStructs.h"
struct PhantomNode { struct PhantomNode {
PhantomNode() : startNode(UINT_MAX), targetNode(UINT_MAX), ratio(1.) {} PhantomNode() : isBidirected(false), edgeBasedNode(UINT_MAX), ratio(1.) {}
bool isBidirected;
NodeID startNode; NodeID edgeBasedNode;
NodeID targetNode;
double ratio; double ratio;
_Coordinate location; _Coordinate location;
void Reset() { void Reset() {
startNode = UINT_MAX; edgeBasedNode = UINT_MAX;
targetNode = UINT_MAX;
ratio = 1.; ratio = 1.;
location.Reset(); location.Reset();
} }
@ -47,28 +45,25 @@ struct PhantomNodes {
targetPhantom.Reset(); targetPhantom.Reset();
} }
bool PhantomsAreOnSameEdge() const { bool PhantomsAreOnSameNodeBasedEdge() const {
return ((startPhantom.startNode == targetPhantom.startNode && startPhantom.targetNode == targetPhantom.targetNode ) || (startPhantom.startNode == targetPhantom.targetNode && targetPhantom.startNode == startPhantom.targetNode)); return (startPhantom.edgeBasedNode == targetPhantom.edgeBasedNode);
} }
bool AtLeastOnePhantomNodeIsUINTMAX() const { 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){ inline std::ostream& operator<<(std::ostream &out, const PhantomNodes & pn){
out << "startNode1: " << pn.startPhantom.startNode << std::endl; out << "Node1: " << pn.startPhantom.edgeBasedNode << std::endl;
out << "startNode2: " << pn.startPhantom.targetNode << std::endl; out << "Node2: " << pn.targetPhantom.edgeBasedNode << std::endl;
out << "targetNode1: " << pn.targetPhantom.startNode << std::endl;
out << "targetNode2: " << pn.targetPhantom.targetNode << std::endl;
out << "startCoord: " << pn.startPhantom.location << std::endl; out << "startCoord: " << pn.startPhantom.location << std::endl;
out << "targetCoord: " << pn.targetPhantom.location << std::endl; out << "targetCoord: " << pn.targetPhantom.location << std::endl;
return out; return out;
} }
struct NodesOfEdge { struct NodesOfEdge {
NodeID startID; NodeID edgeBasedNode;
NodeID destID;
double ratio; double ratio;
_Coordinate projectedPoint; _Coordinate projectedPoint;
}; };

View File

@ -24,6 +24,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include <climits> #include <climits>
#include <deque> #include <deque>
#include <boost/thread.hpp>
#include "BinaryHeap.h" #include "BinaryHeap.h"
#include "PhantomNodes.h" #include "PhantomNodes.h"
#include "../Util/StringUtil.h" #include "../Util/StringUtil.h"
@ -54,51 +56,22 @@ struct _Statistics {
double preprocTime; double preprocTime;
}; };
struct _InsertedNodes { typedef boost::thread_specific_ptr<BinaryHeap< NodeID, NodeID, int, _HeapData > > HeapPtr;
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;
}
}
inline bool isForwardInserted(NodeID n) { template<class EdgeData, class GraphT>
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>
class SearchEngine { class SearchEngine {
private: private:
const GraphT * _graph; const GraphT * _graph;
NodeHelperT * nodeHelpDesk; NodeInformationHelpDesk * nodeHelpDesk;
std::vector<string> * _names; std::vector<string> * _names;
static HeapPtr _forwardHeap;
static HeapPtr _backwardHeap;
inline double absDouble(double input) { if(input < 0) return input*(-1); else return input;} inline double absDouble(double input) { if(input < 0) return input*(-1); else return input;}
public: 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() {} ~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.lat = nodeHelpDesk->getLatitudeOfNode(id);
result.lon = nodeHelpDesk->getLongitudeOfNode(id); result.lon = nodeHelpDesk->getLongitudeOfNode(id);
} }
@ -107,246 +80,197 @@ public:
return nodeHelpDesk->getNumberOfNodes(); 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; if(!_backwardHeap.get())
bool targetEdgeIsReversed = false; _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()) InitializeThreadLocalStorageIfNecessary();
return _upperbound; 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); //insert start and/or target node of target edge id
if(sourceEdgeID == UINT_MAX){ _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; 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); unsigned int ComputeDistanceBetweenNodes(NodeID start, NodeID target) {
if(targetEdgeID == UINT_MAX){ InitializeThreadLocalStorageIfNecessary();
return _upperbound; 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()); unsigned int ComputeDistanceBetweenNodesWithStats(NodeID start, NodeID target, _Statistics & stats) {
_Heap _backwardHeap(nodeHelpDesk->getNumberOfNodes()); 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() ) { inline unsigned int findNearestNodeForLatLon(const _Coordinate & coord, _Coordinate & result) const {
const EdgeData& currentEdgeData = _graph->GetEdgeData(sourceEdgeID); nodeHelpDesk->FindNearestNodeCoordForLatLon(coord, result);
EdgeWeight w = currentEdgeData.distance; return 0;
}
//check if target is reachable from start on same edge inline bool FindRoutingStarts(const _Coordinate & start, const _Coordinate & target, PhantomNodes & routingStarts) {
if(currentEdgeData.forward && currentEdgeData.backward) { nodeHelpDesk->FindRoutingStarts(start, target, routingStarts);
_upperbound = absDouble( w*phantomNodes.targetPhantom.ratio); return true;
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;
}
}
}
//insert start and/or target node of start edge inline bool FindPhantomNodeForCoordinate(const _Coordinate & location, PhantomNode & result) {
const EdgeData& sourceEdgeData = _graph->GetEdgeData(sourceEdgeID); return nodeHelpDesk->FindPhantomNodeForCoordinate(location, result);
EdgeWeight sw = sourceEdgeData.distance; }
if( (sourceEdgeData.backward && !startEdgeIsReversedInGraph) || (sourceEdgeData.forward && startEdgeIsReversedInGraph) ){ inline NodeID GetNameIDForOriginDestinationNodeID(NodeID s, NodeID t) const {
_forwardHeap.Insert(phantomNodes.startPhantom.startNode, absDouble( sw*phantomNodes.startPhantom.ratio), phantomNodes.startPhantom.startNode); //INFO("Getting nameID for s=" << s << " and t=" << t);
_insertedNodes.ForwInsert(phantomNodes.startPhantom.startNode); if(s == t)
} return 0;
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);
}
//insert start and/or target node of target edge id EdgeID e = _graph->FindEdge(s, t);
const EdgeData& targetEdgeData = _graph->GetEdgeData(targetEdgeID); if(e == UINT_MAX)
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)
e = _graph->FindEdge( t, s ); e = _graph->FindEdge( t, s );
if(UINT_MAX == e) { if(UINT_MAX == e) {
// INFO("edge not found for start " << s << ", target " << t) // INFO("edge not found for start " << s << ", target " << t)
return 0; return 0;
} }
assert(e != UINT_MAX); assert(e != UINT_MAX);
const EdgeData ed = _graph->GetEdgeData(e); const EdgeData ed = _graph->GetEdgeData(e);
return ed.middleName.nameID; return ed.via;
} }
inline NodeID GetWeightForOriginDestinationNodeID(NodeID s, NodeID t) const { inline NodeID GetWeightForOriginDestinationNodeID(NodeID s, NodeID t) const {
assert(s!=t); assert(s!=t);
EdgeID e = _graph->FindEdge( s, t ); EdgeID e = _graph->FindEdge(s, t);
if(e == UINT_MAX) if(e == UINT_MAX)
e = _graph->FindEdge( t, s ); e = _graph->FindEdge( t, s );
assert(e != UINT_MAX); assert(e != UINT_MAX);
const EdgeData ed = _graph->GetEdgeData(e); const EdgeData ed = _graph->GetEdgeData(e);
return ed.distance; return ed.distance;
} }
inline std::string &GetUnescapedNameForNameID(const NodeID nameID) const { inline std::string & GetUnescapedNameForNameID(const NodeID nameID) const {
return (nameID >= _names->size() ? _names->at(0) : _names->at(nameID) ); return (nameID >= _names->size() ? _names->at(0) : _names->at(nameID));
} }
inline std::string GetEscapedNameForOriginDestinationNodeID(NodeID s, NodeID t) const { inline std::string GetEscapedNameForOriginDestinationNodeID(NodeID s, NodeID t) const {
NodeID nameID = GetNameIDForOriginDestinationNodeID(s, t); NodeID nameID = GetNameIDForOriginDestinationNodeID(s, t);
return ( GetEscapedNameForNameID(nameID) ); return (GetEscapedNameForNameID(nameID));
} }
inline std::string GetEscapedNameForNameID(const NodeID nameID) const { inline std::string GetEscapedNameForNameID(const NodeID nameID) const {
return ( (nameID >= _names->size() || nameID == 0) ? std::string("") : HTMLEntitize(_names->at(nameID)) ); return ((nameID >= _names->size() || nameID == 0) ? std::string("") : HTMLEntitize(_names->at(nameID)));
} }
inline short GetTypeOfEdgeForOriginDestinationNodeID(NodeID s, NodeID t) const { inline short GetTypeOfEdgeForOriginDestinationNodeID(NodeID s, NodeID t) const {
assert(s!=t); assert(s!=t);
EdgeID e = _graph->FindEdge( s, t ); EdgeID e = _graph->FindEdge(s, t);
if(e == UINT_MAX) if(e == UINT_MAX)
e = _graph->FindEdge( t, s ); e = _graph->FindEdge( t, s );
assert(e != UINT_MAX); assert(e != UINT_MAX);
const EdgeData ed = _graph->GetEdgeData(e); const EdgeData ed = _graph->GetEdgeData(e);
return ed.type; return ed.type;
} }
// inline void RegisterThread(const unsigned k, const unsigned v) {
// nodeHelpDesk->RegisterThread(k,v);
// }
private: 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) { if(distance > *_upperbound){
const NodeID node = _forwardHeap.DeleteMin(); _forwardHeap->DeleteAll();
const unsigned int distance = _forwardHeap.GetKey( node ); return;
if ( _backwardHeap.WasInserted( node ) ) { }
const unsigned int newDistance = _backwardHeap.GetKey( node ) + distance; /* for ( typename GraphT::EdgeIterator edge = _graph->BeginEdges( node ); edge < _graph->EndEdges(node); edge++ ) {
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++ ) {
const NodeID to = _graph->GetTarget(edge); const NodeID to = _graph->GetTarget(edge);
const EdgeWeight edgeWeight = _graph->GetEdgeData(edge).distance; const EdgeWeight edgeWeight = _graph->GetEdgeData(edge).distance;
@ -354,57 +278,57 @@ private:
//Stalling //Stalling
bool backwardDirectionFlag = (!forwardDirection) ? _graph->GetEdgeData(edge).forward : _graph->GetEdgeData(edge).backward; bool backwardDirectionFlag = (!forwardDirection) ? _graph->GetEdgeData(edge).forward : _graph->GetEdgeData(edge).backward;
if(_forwardHeap.WasInserted( to )) { if(_forwardHeap->WasInserted( to )) {
if(backwardDirectionFlag) { if(backwardDirectionFlag) {
if(_forwardHeap.GetKey( to ) + edgeWeight < distance) { if(_forwardHeap->GetKey( to ) + edgeWeight < distance) {
return; 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 NodeID to = _graph->GetTarget(edge);
const EdgeWeight edgeWeight = _graph->GetEdgeData(edge).distance; const EdgeWeight edgeWeight = _graph->GetEdgeData(edge).distance;
assert( edgeWeight > 0 ); assert( edgeWeight > 0 );
const int toDistance = distance + edgeWeight; const int toDistance = distance + edgeWeight;
assert(toDistance > 0);
bool forwardDirectionFlag = (forwardDirection ? _graph->GetEdgeData(edge).forward : _graph->GetEdgeData(edge).backward ); bool forwardDirectionFlag = (forwardDirection ? _graph->GetEdgeData(edge).forward : _graph->GetEdgeData(edge).backward );
if(forwardDirectionFlag) { if(forwardDirectionFlag) {
//New Node discovered -> Add to Heap + Node Info Storage //New Node discovered -> Add to Heap + Node Info Storage
if ( !_forwardHeap.WasInserted( to ) ) { if ( !_forwardHeap->WasInserted( to ) ) {
_forwardHeap.Insert( to, toDistance, node ); _forwardHeap->Insert( to, toDistance, node );
} }
//Found a shorter Path -> Update distance //Found a shorter Path -> Update distance
else if ( toDistance < _forwardHeap.GetKey( to ) ) { else if ( toDistance < _forwardHeap->GetKey( to ) ) {
_forwardHeap.GetData( to ).parent = node; _forwardHeap->GetData( to ).parent = node;
_forwardHeap.DecreaseKey( to, toDistance ); _forwardHeap->DecreaseKey( to, toDistance );
//new parent //new parent
} }
} }
} }
} }
inline void _RoutingStepWithStats( _Heap& _forwardHeap, _Heap &_backwardHeap, const bool& forwardDirection, NodeID * middle, unsigned int * _upperbound, _Statistics& stats) { inline void _RoutingStepWithStats(HeapPtr & _forwardHeap, HeapPtr & _backwardHeap, const bool & forwardDirection, NodeID *middle, unsigned int *_upperbound, _Statistics & stats) {
const NodeID node = _forwardHeap.DeleteMin(); const NodeID node = _forwardHeap->DeleteMin();
stats.deleteMins++; stats.deleteMins++;
const unsigned int distance = _forwardHeap.GetKey( node ); const unsigned int distance = _forwardHeap->GetKey(node);
if ( _backwardHeap.WasInserted( node ) ) { if(_backwardHeap->WasInserted(node)){
const unsigned int newDistance = _backwardHeap.GetKey( node ) + distance; const unsigned int newDistance = _backwardHeap->GetKey(node) + distance;
if ( newDistance < *_upperbound ) { if(newDistance < *_upperbound){
*middle = node; *middle = node;
*_upperbound = newDistance; *_upperbound = newDistance;
} }
} }
if ( distance > *_upperbound ) {
stats.meetingNodes++;
_forwardHeap.DeleteAll();
return;
}
if(distance > *_upperbound) {
for ( typename GraphT::EdgeIterator edge = _graph->BeginEdges( node ); edge < _graph->EndEdges(node); edge++ ) { 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 EdgeData& ed = _graph->GetEdgeData(edge);
const NodeID to = _graph->GetTarget(edge); const NodeID to = _graph->GetTarget(edge);
const EdgeWeight edgeWeight = ed.distance; const EdgeWeight edgeWeight = ed.distance;
@ -413,9 +337,9 @@ private:
const int toDistance = distance + edgeWeight; const int toDistance = distance + edgeWeight;
//Stalling //Stalling
if(_forwardHeap.WasInserted( to )) { if(_forwardHeap->WasInserted( to )) {
if(!forwardDirection ? ed.forward : ed.backward) { if(!forwardDirection ? ed.forward : ed.backward) {
if(_forwardHeap.GetKey( to ) + edgeWeight < distance) { if(_forwardHeap->GetKey( to ) + edgeWeight < distance) {
stats.stalledNodes++; stats.stalledNodes++;
return; return;
} }
@ -424,57 +348,62 @@ private:
if(forwardDirection ? ed.forward : ed.backward ) { if(forwardDirection ? ed.forward : ed.backward ) {
//New Node discovered -> Add to Heap + Node Info Storage //New Node discovered -> Add to Heap + Node Info Storage
if ( !_forwardHeap.WasInserted( to ) ) { if ( !_forwardHeap->WasInserted( to ) ) {
_forwardHeap.Insert( to, toDistance, node ); _forwardHeap->Insert( to, toDistance, node );
stats.insertedNodes++; stats.insertedNodes++;
} }
//Found a shorter Path -> Update distance //Found a shorter Path -> Update distance
else if ( toDistance < _forwardHeap.GetKey( to ) ) { else if ( toDistance < _forwardHeap->GetKey( to ) ) {
_forwardHeap.GetData( to ).parent = node; _forwardHeap->GetData( to ).parent = node;
_forwardHeap.DecreaseKey( to, toDistance ); _forwardHeap->DecreaseKey( to, toDistance );
stats.decreasedNodes++; stats.decreasedNodes++;
//new parent //new parent
} }
} }
} }
} }
inline bool _UnpackEdge( const NodeID source, const NodeID target, std::vector< _PathData >& path ) { inline bool _UnpackEdge(const NodeID source, const NodeID target, std::vector<_PathData> & path) {
assert(source != target); assert(source != target);
//find edge first. //find edge first.
bool forward = true; typename GraphT::EdgeIterator smallestEdge = SPECIAL_EDGEID;
typename GraphT::EdgeIterator smallestEdge = SPECIAL_EDGEID; EdgeWeight smallestWeight = UINT_MAX;
EdgeWeight smallestWeight = UINT_MAX; for(typename GraphT::EdgeIterator eit = _graph->BeginEdges(source);eit < _graph->EndEdges(source);eit++){
for(typename GraphT::EdgeIterator eit = _graph->BeginEdges(source); eit < _graph->EndEdges(source); eit++) { const EdgeWeight weight = _graph->GetEdgeData(eit).distance;
const EdgeWeight weight = _graph->GetEdgeData(eit).distance; if(_graph->GetTarget(eit) == target && weight < smallestWeight && _graph->GetEdgeData(eit).forward){
if(_graph->GetTarget(eit) == target && weight < smallestWeight && _graph->GetEdgeData(eit).forward) { smallestEdge = eit;
smallestEdge = eit; smallestWeight = weight; 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;
}
}
}
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); const EdgeData& ed = _graph->GetEdgeData(smallestEdge);
// INFO( (ed.shortcut ? "SHRT: " : "ORIG: ") << ed.distance << "," << ed.via);
if(ed.shortcut) {//unpack if(ed.shortcut) {//unpack
const NodeID middle = ed.middleName.middle; const NodeID middle = ed.via;
_UnpackEdge(source, middle, path); _UnpackEdge(source, middle, path);
_UnpackEdge(middle, target, path); _UnpackEdge(middle, target, path);
return false; return false;
} else { } else {
assert(!ed.shortcut); assert(!ed.shortcut);
path.push_back(_PathData(target) ); path.push_back(_PathData(ed.via) );
return true; 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_ */ #endif /* SEARCHENGINE_H_ */

View File

@ -49,7 +49,7 @@ public:
} }
}; };
StaticGraph( int nodes, std::vector< InputEdge > &graph ) { StaticGraph( const int nodes, std::vector< InputEdge > &graph ) {
#ifdef _GLIBCXX_PARALLEL #ifdef _GLIBCXX_PARALLEL
__gnu_parallel::sort( graph.begin(), graph.end() ); __gnu_parallel::sort( graph.begin(), graph.end() );
#else #else
@ -62,9 +62,8 @@ public:
EdgeIterator position = 0; EdgeIterator position = 0;
for ( NodeIterator node = 0; node <= _numNodes; ++node ) { for ( NodeIterator node = 0; node <= _numNodes; ++node ) {
EdgeIterator lastEdge = edge; EdgeIterator lastEdge = edge;
while ( edge < _numEdges && graph[edge].source == node ) { while ( edge < _numEdges && graph[edge].source == node )
++edge; ++edge;
}
_nodes[node].firstEdge = position; //=edge _nodes[node].firstEdge = position; //=edge
position += edge - lastEdge; //remove position += edge - lastEdge; //remove
} }

View File

@ -50,7 +50,7 @@ public:
if( ! path.size() ) if( ! path.size() )
continue; continue;
for(vector< _PathData >::const_iterator it = path.begin(); it != path.end(); it++) { for(vector< _PathData >::const_iterator it = path.begin(); it != path.end(); it++) {
sEngine.getCoordinatesForNodeID(it->node, current); sEngine.GetCoordinatesForNodeID(it->node, current);
convertInternalLatLonToString(current.lat, tmp); convertInternalLatLonToString(current.lat, tmp);
reply.content += "<rtept lat=\"" + tmp + "\" "; reply.content += "<rtept lat=\"" + tmp + "\" ";

View File

@ -21,6 +21,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef JSON_DESCRIPTOR_H_ #ifndef JSON_DESCRIPTOR_H_
#define JSON_DESCRIPTOR_H_ #define JSON_DESCRIPTOR_H_
#include <boost/foreach.hpp>
#include "BaseDescriptor.h" #include "BaseDescriptor.h"
#include "../DataStructures/PolylineCompressor.h" #include "../DataStructures/PolylineCompressor.h"
@ -48,143 +50,18 @@ public:
//Put first segment of route into geometry //Put first segment of route into geometry
polyline.push_back(phantomNodes.startPhantom.location); polyline.push_back(phantomNodes.startPhantom.location);
descriptorState.geometryCounter++;
descriptorState.startOfSegmentCoordinate = phantomNodes.startPhantom.location;
//Generate initial instruction for start of route (order of NodeIDs does not matter, its the same name anyway)
summary.startName = sEngine.GetEscapedNameForOriginDestinationNodeID(phantomNodes.startPhantom.startNode, phantomNodes.startPhantom.targetNode);
descriptorState.lastNameID = sEngine.GetNameIDForOriginDestinationNodeID(phantomNodes.startPhantom.startNode, phantomNodes.startPhantom.targetNode);
//If we have a route, i.e. start and dest not on same edge, than get it
if(rawRoute.routeSegments[0].size() > 0)
sEngine.getCoordinatesForNodeID(rawRoute.routeSegments[0].begin()->node, descriptorState.tmpCoord);
else
descriptorState.tmpCoord = phantomNodes.targetPhantom.location;
descriptorState.previousCoordinate = phantomNodes.startPhantom.location;
descriptorState.currentCoordinate = descriptorState.tmpCoord;
descriptorState.distanceOfInstruction += ApproximateDistance(descriptorState.previousCoordinate, descriptorState.currentCoordinate);
if(config.instructions) {
//Get Heading
double angle = GetAngleBetweenTwoEdges(_Coordinate(phantomNodes.startPhantom.location.lat, phantomNodes.startPhantom.location.lon), descriptorState.tmpCoord, _Coordinate(descriptorState.tmpCoord.lat, descriptorState.tmpCoord.lon-1000));
getDirectionOfInstruction(angle, directionOfInstruction);
appendInstructionNameToString(summary.startName, directionOfInstruction.direction, descriptorState.routeInstructionString, true);
}
NodeID lastNodeID = UINT_MAX;
for(unsigned segmentIdx = 0; segmentIdx < rawRoute.routeSegments.size(); segmentIdx++) { for(unsigned segmentIdx = 0; segmentIdx < rawRoute.routeSegments.size(); segmentIdx++) {
const std::vector< _PathData > & path = rawRoute.routeSegments[segmentIdx]; const std::vector< _PathData > & path = rawRoute.routeSegments[segmentIdx];
if(path.empty()) BOOST_FOREACH(_PathData pathData, path) {
continue; _Coordinate current;
if ( UINT_MAX == lastNodeID) { sEngine.GetCoordinatesForNodeID(pathData.node, current);
lastNodeID = (phantomNodes.startPhantom.startNode == (*path.begin()).node ? phantomNodes.startPhantom.targetNode : phantomNodes.startPhantom.startNode); polyline.push_back(current);
} // INFO(pathData.node << " at " << current.lat << "," << current.lon);
//Check, if there is overlap between current and previous route segment //INFO("routed over node: " << pathData.node);
//if not, than we are fine and can route over this edge without paying any special attention.
if(lastNodeID == (*path.begin()).node) {
// appendCoordinateToString(descriptorState.currentCoordinate, descriptorState.routeGeometryString);
polyline.push_back(descriptorState.currentCoordinate);
descriptorState.geometryCounter++;
lastNodeID = (lastNodeID == rawRoute.segmentEndCoordinates[segmentIdx].startPhantom.startNode ? rawRoute.segmentEndCoordinates[segmentIdx].targetPhantom.startNode : rawRoute.segmentEndCoordinates[segmentIdx].startPhantom.startNode);
//output of the via nodes coordinates
polyline.push_back(rawRoute.segmentEndCoordinates[segmentIdx].startPhantom.location);
descriptorState.geometryCounter++;
descriptorState.currentNameID = sEngine.GetNameIDForOriginDestinationNodeID(rawRoute.segmentEndCoordinates[segmentIdx].startPhantom.startNode, rawRoute.segmentEndCoordinates[segmentIdx].startPhantom.targetNode);
//Make a special announement to do a U-Turn.
appendInstructionLengthToString(descriptorState.distanceOfInstruction, descriptorState.routeInstructionString);
descriptorState.routeInstructionString += ",";
descriptorState.distanceOfInstruction = ApproximateDistance(descriptorState.currentCoordinate, rawRoute.segmentEndCoordinates[segmentIdx].startPhantom.location);
getTurnDirectionOfInstruction(descriptorState.GetAngleBetweenCoordinates(), tmp);
appendInstructionNameToString(sEngine.GetEscapedNameForNameID(descriptorState.currentNameID), tmp, descriptorState.routeInstructionString);
appendInstructionLengthToString(descriptorState.distanceOfInstruction, descriptorState.routeInstructionString);
descriptorState.routeInstructionString += ",";
tmp = "U-turn at via point";
appendInstructionNameToString(sEngine.GetEscapedNameForNameID(descriptorState.currentNameID), tmp, descriptorState.routeInstructionString);
double tmpDistance = descriptorState.distanceOfInstruction;
descriptorState.SetStartOfSegment(); //Set start of segment but save distance information.
descriptorState.distanceOfInstruction = tmpDistance;
} else if(segmentIdx > 0) { //We are going straight through an edge which is carrying the via point.
assert(segmentIdx != 0);
//routeInstructionString += "reaching via node: ";
descriptorState.nextCoordinate = rawRoute.segmentEndCoordinates[segmentIdx].startPhantom.location;
descriptorState.currentNameID = sEngine.GetNameIDForOriginDestinationNodeID(rawRoute.segmentEndCoordinates[segmentIdx].startPhantom.startNode, rawRoute.segmentEndCoordinates[segmentIdx].startPhantom.targetNode);
polyline.push_back(descriptorState.currentCoordinate);
descriptorState.geometryCounter++;
polyline.push_back(rawRoute.segmentEndCoordinates[segmentIdx].startPhantom.location);
descriptorState.geometryCounter++;
if(config.instructions) {
double turnAngle = descriptorState.GetAngleBetweenCoordinates();
appendInstructionLengthToString(descriptorState.distanceOfInstruction, descriptorState.routeInstructionString);
descriptorState.SetStartOfSegment();
descriptorState.routeInstructionString += ",";
getTurnDirectionOfInstruction(turnAngle, tmp);
tmp += " and reach via point";
appendInstructionNameToString(sEngine.GetEscapedNameForNameID(descriptorState.currentNameID), tmp, descriptorState.routeInstructionString);
//instruction to continue on the segment
appendInstructionLengthToString(ApproximateDistance(descriptorState.currentCoordinate, descriptorState.nextCoordinate), descriptorState.routeInstructionString);
descriptorState.entireDistance += ApproximateDistance(descriptorState.currentCoordinate, descriptorState.nextCoordinate);
descriptorState.routeInstructionString += ",";
appendInstructionNameToString(sEngine.GetEscapedNameForNameID(descriptorState.currentNameID), "Continue ", descriptorState.routeInstructionString);
//note the new segment starting coordinates
descriptorState.SetStartOfSegment();
descriptorState.previousCoordinate = descriptorState.currentCoordinate;
descriptorState.currentCoordinate = descriptorState.nextCoordinate;
}
}
for(vector< _PathData >::const_iterator it = path.begin(); it != path.end(); it++) {
sEngine.getCoordinatesForNodeID(it->node, descriptorState.nextCoordinate);
descriptorState.currentNameID = sEngine.GetNameIDForOriginDestinationNodeID(lastNodeID, it->node);
double area = fabs(0.5*( descriptorState.startOfSegmentCoordinate.lon*(descriptorState.nextCoordinate.lat - descriptorState.currentCoordinate.lat) + descriptorState.nextCoordinate.lon*(descriptorState.currentCoordinate.lat - descriptorState.startOfSegmentCoordinate.lat) + descriptorState.currentCoordinate.lon*(descriptorState.startOfSegmentCoordinate.lat - descriptorState.nextCoordinate.lat) ) );
//if route is generalization does not skip this point, add it to description
if( config.z == 19 || area >= areaThresholds[config.z] || (false == descriptorState.CurrentAndPreviousNameIDsEqual()) ) {
//mark the beginning of the segment thats announced
// appendCoordinateToString(descriptorState.currentCoordinate, descriptorState.routeGeometryString);
polyline.push_back(descriptorState.currentCoordinate);
descriptorState.geometryCounter++;
if( ( false == descriptorState.CurrentAndPreviousNameIDsEqual() ) && config.instructions) {
appendInstructionLengthToString(descriptorState.distanceOfInstruction, descriptorState.routeInstructionString);
descriptorState.routeInstructionString += ",";
getTurnDirectionOfInstruction(descriptorState.GetAngleBetweenCoordinates(), tmp);
appendInstructionNameToString(sEngine.GetEscapedNameForNameID(descriptorState.currentNameID), tmp, descriptorState.routeInstructionString);
//note the new segment starting coordinates
descriptorState.SetStartOfSegment();
}
}
descriptorState.distanceOfInstruction += ApproximateDistance(descriptorState.currentCoordinate, descriptorState.nextCoordinate);
lastNodeID = it->node;
if(it != path.begin()) {
descriptorState.previousCoordinate = descriptorState.currentCoordinate;
descriptorState.currentCoordinate = descriptorState.nextCoordinate;
}
} }
} }
descriptorState.currentNameID = sEngine.GetNameIDForOriginDestinationNodeID(phantomNodes.targetPhantom.startNode, phantomNodes.targetPhantom.targetNode);
descriptorState.nextCoordinate = phantomNodes.targetPhantom.location;
polyline.push_back(descriptorState.currentCoordinate);
descriptorState.geometryCounter++;
if((false == descriptorState.CurrentAndPreviousNameIDsEqual()) && config.instructions) {
appendInstructionLengthToString(descriptorState.distanceOfInstruction, descriptorState.routeInstructionString);
descriptorState.routeInstructionString += ",";
getTurnDirectionOfInstruction(descriptorState.GetAngleBetweenCoordinates(), tmp);
appendInstructionNameToString(sEngine.GetEscapedNameForNameID(descriptorState.currentNameID), tmp, descriptorState.routeInstructionString);
descriptorState.distanceOfInstruction = 0;
descriptorState.SetStartOfSegment();
}
summary.destName = sEngine.GetEscapedNameForNameID(descriptorState.currentNameID);
descriptorState.distanceOfInstruction += ApproximateDistance(descriptorState.currentCoordinate, descriptorState.nextCoordinate);
polyline.push_back(phantomNodes.targetPhantom.location); polyline.push_back(phantomNodes.targetPhantom.location);
descriptorState.geometryCounter++;
appendInstructionLengthToString(descriptorState.distanceOfInstruction, descriptorState.routeInstructionString);
summary.BuildDurationAndLengthStrings(descriptorState.entireDistance, distance);
} else { } else {
//no route found //no route found
reply.content += "207," reply.content += "207,"

View File

@ -1,249 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef KML_DESCRIPTOR_H_
#define KML_DESCRIPTOR_H_
#include "BaseDescriptor.h"
template<class SearchEngineT>
class KMLDescriptor : public BaseDescriptor<SearchEngineT>{
private:
_DescriptorConfig config;
RouteSummary summary;
DirectionOfInstruction directionOfInstruction;
DescriptorState descriptorState;
std::string tmp;
public:
KMLDescriptor() {}
void SetConfig(const _DescriptorConfig & c) { config = c; }
void Run(http::Reply & reply, RawRouteData &rawRoute, PhantomNodes &phantomNodes, SearchEngineT &sEngine, unsigned distance) {
WriteHeaderToOutput(reply.content);
//We do not need to do much, if there is no route ;-)
if(distance != UINT_MAX && rawRoute.routeSegments.size() > 0) {
//Put first segment of route into geometry
appendCoordinateToString(phantomNodes.startPhantom.location, descriptorState.routeGeometryString);
descriptorState.startOfSegmentCoordinate = phantomNodes.startPhantom.location;
//Generate initial instruction for start of route (order of NodeIDs does not matter, its the same name anyway)
summary.startName = sEngine.GetEscapedNameForOriginDestinationNodeID(phantomNodes.startPhantom.startNode, phantomNodes.startPhantom.targetNode);
descriptorState.lastNameID = sEngine.GetNameIDForOriginDestinationNodeID(phantomNodes.startPhantom.startNode, phantomNodes.startPhantom.targetNode);
//If we have a route, i.e. start and dest not on same edge, than get it
if(rawRoute.routeSegments[0].size() > 0)
sEngine.getCoordinatesForNodeID(rawRoute.routeSegments[0].begin()->node, descriptorState.tmpCoord);
else
descriptorState.tmpCoord = phantomNodes.targetPhantom.location;
descriptorState.previousCoordinate = phantomNodes.startPhantom.location;
descriptorState.currentCoordinate = descriptorState.tmpCoord;
descriptorState.distanceOfInstruction += ApproximateDistance(descriptorState.previousCoordinate, descriptorState.currentCoordinate);
if(config.instructions) {
//Get Heading
double angle = GetAngleBetweenTwoEdges(_Coordinate(phantomNodes.startPhantom.location.lat, phantomNodes.startPhantom.location.lon), descriptorState.tmpCoord, _Coordinate(descriptorState.tmpCoord.lat, descriptorState.tmpCoord.lon-1000));
getDirectionOfInstruction(angle, directionOfInstruction);
appendInstructionNameToString(summary.startName, directionOfInstruction.direction, descriptorState.routeInstructionString, true);
}
NodeID lastNodeID = UINT_MAX;
for(unsigned segmentIdx = 0; segmentIdx < rawRoute.routeSegments.size(); segmentIdx++) {
const std::vector< _PathData > & path = rawRoute.routeSegments[segmentIdx];
if( ! path.size() )
continue;
if ( UINT_MAX == lastNodeID) {
lastNodeID = (phantomNodes.startPhantom.startNode == (*path.begin()).node ? phantomNodes.startPhantom.targetNode : phantomNodes.startPhantom.startNode);
}
//Check, if there is overlap between current and previous route segment
//if not, than we are fine and can route over this edge without paying any special attention.
if(lastNodeID == (*path.begin()).node) {
appendCoordinateToString(descriptorState.currentCoordinate, descriptorState.routeGeometryString);
lastNodeID = (lastNodeID == rawRoute.segmentEndCoordinates[segmentIdx].startPhantom.startNode ? rawRoute.segmentEndCoordinates[segmentIdx].startPhantom.targetNode : rawRoute.segmentEndCoordinates[segmentIdx].startPhantom.startNode);
//output of the via nodes coordinates
appendCoordinateToString(rawRoute.segmentEndCoordinates[segmentIdx].startPhantom.location, descriptorState.routeGeometryString);
descriptorState.currentNameID = sEngine.GetNameIDForOriginDestinationNodeID(rawRoute.segmentEndCoordinates[segmentIdx].startPhantom.startNode, rawRoute.segmentEndCoordinates[segmentIdx].targetPhantom.startNode);
//Make a special announement to do a U-Turn.
appendInstructionLengthToString(descriptorState.distanceOfInstruction, descriptorState.routeInstructionString);
descriptorState.distanceOfInstruction = ApproximateDistance(descriptorState.currentCoordinate, rawRoute.segmentEndCoordinates[segmentIdx].startPhantom.location);
getTurnDirectionOfInstruction(descriptorState.GetAngleBetweenCoordinates(), tmp);
appendInstructionNameToString(sEngine.GetEscapedNameForNameID(descriptorState.currentNameID), tmp, descriptorState.routeInstructionString);
appendInstructionLengthToString(descriptorState.distanceOfInstruction, descriptorState.routeInstructionString);
tmp = "U-turn at via point";
appendInstructionNameToString(sEngine.GetEscapedNameForNameID(descriptorState.currentNameID), tmp, descriptorState.routeInstructionString);
double tmpDistance = descriptorState.distanceOfInstruction;
descriptorState.SetStartOfSegment(); //Set start of segment but save distance information.
descriptorState.distanceOfInstruction = tmpDistance;
} else if(segmentIdx > 0) { //We are going straight through an edge which is carrying the via point.
assert(segmentIdx != 0);
//routeInstructionString += "\nreaching via node: \n";
descriptorState.nextCoordinate = rawRoute.segmentEndCoordinates[segmentIdx].startPhantom.location;
descriptorState.currentNameID = sEngine.GetNameIDForOriginDestinationNodeID(rawRoute.segmentEndCoordinates[segmentIdx].startPhantom.startNode, rawRoute.segmentEndCoordinates[segmentIdx].targetPhantom.startNode);
appendCoordinateToString(descriptorState.currentCoordinate, descriptorState.routeGeometryString);
appendCoordinateToString(rawRoute.segmentEndCoordinates[segmentIdx].startPhantom.location, descriptorState.routeGeometryString);
if(config.instructions) {
double turnAngle = descriptorState.GetAngleBetweenCoordinates();
appendInstructionLengthToString(descriptorState.distanceOfInstruction, descriptorState.routeInstructionString);
getTurnDirectionOfInstruction(turnAngle, tmp);
tmp += " and reach via point";
appendInstructionNameToString(sEngine.GetEscapedNameForNameID(descriptorState.currentNameID), tmp, descriptorState.routeInstructionString);
//instruction to continue on the segment
appendInstructionLengthToString(ApproximateDistance(descriptorState.currentCoordinate, descriptorState.nextCoordinate), descriptorState.routeInstructionString);
appendInstructionNameToString(sEngine.GetEscapedNameForNameID(descriptorState.currentNameID), "Continue on", descriptorState.routeInstructionString);
//note the new segment starting coordinates
descriptorState.SetStartOfSegment();
descriptorState.previousCoordinate = descriptorState.currentCoordinate;
descriptorState.currentCoordinate = descriptorState.nextCoordinate;
} else {
assert(false);
}
}
for(vector< _PathData >::const_iterator it = path.begin(); it != path.end(); it++) {
sEngine.getCoordinatesForNodeID(it->node, descriptorState.nextCoordinate);
descriptorState.currentNameID = sEngine.GetNameIDForOriginDestinationNodeID(lastNodeID, it->node);
double area = fabs(0.5*( descriptorState.startOfSegmentCoordinate.lon*(descriptorState.nextCoordinate.lat - descriptorState.currentCoordinate.lat) + descriptorState.nextCoordinate.lon*(descriptorState.currentCoordinate.lat - descriptorState.startOfSegmentCoordinate.lat) + descriptorState.currentCoordinate.lon*(descriptorState.startOfSegmentCoordinate.lat - descriptorState.nextCoordinate.lat) ) );
//if route is generalization does not skip this point, add it to description
if( it==path.end()-1 || config.z == 19 || area >= areaThresholds[config.z] || (false == descriptorState.CurrentAndPreviousNameIDsEqual()) ) {
//mark the beginning of the segment thats announced
appendCoordinateToString(descriptorState.currentCoordinate, descriptorState.routeGeometryString);
if( ( false == descriptorState.CurrentAndPreviousNameIDsEqual() ) && config.instructions) {
appendInstructionLengthToString(descriptorState.distanceOfInstruction, descriptorState.routeInstructionString);
getTurnDirectionOfInstruction(descriptorState.GetAngleBetweenCoordinates(), tmp);
appendInstructionNameToString(sEngine.GetEscapedNameForNameID(descriptorState.currentNameID), tmp, descriptorState.routeInstructionString);
//note the new segment starting coordinates
descriptorState.SetStartOfSegment();
}
}
descriptorState.distanceOfInstruction += ApproximateDistance(descriptorState.currentCoordinate, descriptorState.nextCoordinate);
lastNodeID = it->node;
if(it != path.begin()) {
descriptorState.previousCoordinate = descriptorState.currentCoordinate;
descriptorState.currentCoordinate = descriptorState.nextCoordinate;
}
}
}
descriptorState.currentNameID = sEngine.GetNameIDForOriginDestinationNodeID(phantomNodes.targetPhantom.startNode, phantomNodes.startPhantom.targetNode);
descriptorState.nextCoordinate = phantomNodes.targetPhantom.location;
appendCoordinateToString(descriptorState.currentCoordinate, descriptorState.routeGeometryString);
if((false == descriptorState.CurrentAndPreviousNameIDsEqual()) && config.instructions) {
appendInstructionLengthToString(descriptorState.distanceOfInstruction, descriptorState.routeInstructionString);
getTurnDirectionOfInstruction(descriptorState.GetAngleBetweenCoordinates(), tmp);
appendInstructionNameToString(sEngine.GetEscapedNameForNameID(descriptorState.currentNameID), tmp, descriptorState.routeInstructionString);
descriptorState.distanceOfInstruction = 0;
}
summary.destName = sEngine.GetEscapedNameForNameID(descriptorState.currentNameID);
descriptorState.distanceOfInstruction += ApproximateDistance(descriptorState.currentCoordinate, descriptorState.nextCoordinate);
appendCoordinateToString(phantomNodes.targetPhantom.location, descriptorState.routeGeometryString);
appendInstructionLengthToString(descriptorState.distanceOfInstruction, descriptorState.routeInstructionString);
descriptorState.SetStartOfSegment();
//compute distance/duration for route summary
ostringstream s;
s << 10*(round(descriptorState.entireDistance/10.));
summary.lengthString = s.str();
int travelTime = 60*(distance/60.) + 1;
s.str("");
s << travelTime;
summary.durationString = s.str();
//writing summary of route to reply
reply.content += "<Placemark><name><![CDATA[Route from ";
reply.content += summary.startName;
reply.content += " to ";
reply.content += summary.destName;
reply.content += "]]></name><description><![CDATA[Distance: ";
reply.content += summary.lengthString;
reply.content += "&#160;m (approx. ";
reply.content += summary.durationString;
reply.content += " minutes)]]></description>\n";
reply.content += "<GeometryCollection><LineString><coordinates>";
if(config.geometry)
reply.content += descriptorState.routeGeometryString;
reply.content += "</coordinates></LineString></GeometryCollection>";
reply.content += "</Placemark>";
//list all viapoints so that the client may display it
std::cout << "number of segment endpoints in route: " << rawRoute.segmentEndCoordinates.size() << std::endl;
for(unsigned segmentIdx = 1; (true == config.geometry) && (segmentIdx < rawRoute.segmentEndCoordinates.size()); segmentIdx++) {
reply.content += "<Placemark>";
reply.content += "<name>Via Point 1</name>";
reply.content += "<Point>";
reply.content += "<coordinates>";
appendCoordinateToString(rawRoute.segmentEndCoordinates[segmentIdx].startPhantom.location, reply.content);
reply.content += "</coordinates>";
reply.content += "</Point>";
reply.content += "</Placemark>";
}
}
reply.content += descriptorState.routeInstructionString;
reply.content += "</Document>\n</kml>";
std::cout << descriptorState.routeInstructionString << std::endl;
}
private:
void appendCoordinateToString(const _Coordinate coordinate, std::string & output) {
if(config.geometry) {
convertInternalCoordinateToString(coordinate, tmp);
output += tmp;
}
}
void appendInstructionNameToString(const std::string & nameOfStreet, const std::string & instructionOrDirection, std::string &output, bool firstAdvice = false) {
if(config.instructions) {
output += "<placemark><name><![CDATA[";
if(firstAdvice) {
output += "Head on ";
output += nameOfStreet;
output += " direction ";
output += instructionOrDirection;
} else {
output += instructionOrDirection;
output += " on ";
output += nameOfStreet;
}
output += "]]></name>";
}
}
void appendInstructionLengthToString(unsigned length, std::string &output) {
if(config.instructions){
output += "\n\t<description>drive for ";
intToString(10*(round(length/10.)), tmp);
output += tmp;
output += "m</description></placemark>";
output += "\n";
}
}
void WriteHeaderToOutput(std::string & output) {
output = ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<kml xmlns=\"http://www.opengis.net/kml/2.2\">\n<Document>\n");
}
};
#endif /* KML_DESCRIPTOR_H_ */

View File

@ -28,28 +28,30 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "../DataStructures/StaticGraph.h" #include "../DataStructures/StaticGraph.h"
#include "../Util/GraphLoader.h" #include "../Util/GraphLoader.h"
typedef StaticGraph<EdgeData> QueryGraph;
typedef QueryGraph::InputEdge InputEdge;
struct ObjectsForQueryStruct { struct ObjectsForQueryStruct {
typedef StaticGraph<EdgeData> QueryGraph;
typedef QueryGraph::InputEdge InputEdge;
NodeInformationHelpDesk * nodeHelpDesk; NodeInformationHelpDesk * nodeHelpDesk;
std::vector<std::string> * names; std::vector<std::string> * names;
QueryGraph * graph; QueryGraph * graph;
ObjectsForQueryStruct(std::string hsgrPath, std::string ramIndexPath, std::string fileIndexPath, std::string nodesPath, std::string namesPath, std::string psd = "route") { ObjectsForQueryStruct(std::string hsgrPath, std::string ramIndexPath, std::string fileIndexPath, std::string nodesPath, std::string namesPath, std::string psd = "route") {
std::cout << "[objects] loading query data structures ..." << std::flush; std::cout << "[objects] loading query data structures ..." << std::flush;
//Init nearest neighbor data structure
ifstream nodesInStream(nodesPath.c_str(), ios::binary);
nodeHelpDesk = new NodeInformationHelpDesk(ramIndexPath.c_str(), fileIndexPath.c_str());
nodeHelpDesk->initNNGrid(nodesInStream);
ifstream hsgrInStream(hsgrPath.c_str(), ios::binary); ifstream hsgrInStream(hsgrPath.c_str(), ios::binary);
//Deserialize road network graph //Deserialize road network graph
std::vector< InputEdge> edgeList; std::vector< InputEdge> edgeList;
readHSGRFromStream(hsgrInStream, edgeList); const int n = readHSGRFromStream(hsgrInStream, edgeList);
graph = new QueryGraph(nodeHelpDesk->getNumberOfNodes()-1, edgeList); INFO("Graph has " << n << " nodes");
graph = new QueryGraph(n, edgeList);
std::vector< InputEdge >().swap( edgeList ); //free memory std::vector< InputEdge >().swap( edgeList ); //free memory
//Init nearest neighbor data structure
ifstream nodesInStream(nodesPath.c_str(), ios::binary);
nodeHelpDesk = new NodeInformationHelpDesk(ramIndexPath.c_str(), fileIndexPath.c_str(), n);
nodeHelpDesk->initNNGrid(nodesInStream);
//deserialize street name list //deserialize street name list
ifstream namesInStream(namesPath.c_str(), ios::binary); ifstream namesInStream(namesPath.c_str(), ios::binary);
unsigned size(0); unsigned size(0);

View File

@ -1,209 +0,0 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef ROUTEPLUGIN_H_
#define ROUTEPLUGIN_H_
#include <cstdlib>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include "ObjectForPluginStruct.h"
#include "BaseDescriptor.h"
#include "BasePlugin.h"
#include "RouteParameters.h"
#include "KMLDescriptor.h"
#include "JSONDescriptor.h"
#include "GPXDescriptor.h"
#include "../DataStructures/HashTable.h"
#include "../DataStructures/StaticGraph.h"
#include "../DataStructures/SearchEngine.h"
#include "../Util/StringUtil.h"
class RoutePlugin : public BasePlugin {
public:
RoutePlugin(ObjectsForQueryStruct * objects, std::string psd = "route") : pluginDescriptorString(psd) {
nodeHelpDesk = objects->nodeHelpDesk;
graph = objects->graph;
names = objects->names;
sEngine = new SearchEngine<EdgeData, StaticGraph<EdgeData> >(graph, nodeHelpDesk, names);
descriptorTable.Set("", 0); //default descriptor
descriptorTable.Set("kml", 0);
descriptorTable.Set("json", 1);
descriptorTable.Set("gpx", 2);
}
virtual ~RoutePlugin() {
DELETE(sEngine);
}
std::string GetDescriptor() { return pluginDescriptorString; }
std::string GetVersionString() { return std::string("0.3 (DL)"); }
void HandleRequest(RouteParameters routeParameters, http::Reply& reply) {
//check number of parameters
if(routeParameters.parameters.size() != 4) {
reply = http::Reply::stockReply(http::Reply::badRequest);
return;
}
int lat1 = static_cast<int>(100000.*atof(routeParameters.parameters[0].c_str()));
int lon1 = static_cast<int>(100000.*atof(routeParameters.parameters[1].c_str()));
int lat2 = static_cast<int>(100000.*atof(routeParameters.parameters[2].c_str()));
int lon2 = static_cast<int>(100000.*atof(routeParameters.parameters[3].c_str()));
_DescriptorConfig descriptorConfig;
if("false" == routeParameters.options["geometry"]) {
descriptorConfig.geometry = false;
}
if(lat1>90*100000 || lat1 <-90*100000 || lon1>180*100000 || lon1 <-180*100000) {
reply = http::Reply::stockReply(http::Reply::badRequest);
return;
}
if(lat2>90*100000 || lat2 <-90*100000 || lon2>180*100000 || lon2 <-180*100000) {
reply = http::Reply::stockReply(http::Reply::badRequest);
return;
}
_Coordinate startCoord(lat1, lon1);
_Coordinate targetCoord(lat2, lon2);
vector< _PathData > path;
RawRouteData rawRoute;
PhantomNodes phantomNodes;
sEngine->FindRoutingStarts(startCoord, targetCoord, phantomNodes);
unsigned int distance = sEngine->ComputeRoute(phantomNodes, path);
rawRoute.routeSegments.push_back(path);
reply.status = http::Reply::ok;
BaseDescriptor<SearchEngine<EdgeData, StaticGraph<EdgeData> > > * desc;
std::string JSONParameter = routeParameters.options.Find("jsonp");
if("" != JSONParameter) {
reply.content += JSONParameter;
reply.content += "(\n";
}
unsigned descriptorType = descriptorTable[routeParameters.options.Find("output")];
unsigned short zoom = 18;
if(routeParameters.options.Find("z") != ""){
zoom = atoi(routeParameters.options.Find("z").c_str());
if(18 < zoom)
zoom = 18;
}
descriptorConfig.z = zoom;
if(routeParameters.options.Find("instructions") == "false") {
descriptorConfig.instructions = false;
}
if(routeParameters.options.Find("geometry") == "false" ) {
descriptorConfig.geometry = false;
}
if("cmp" == routeParameters.options.Find("geomformat") || "cmp6" == routeParameters.options.Find("geomformat") ) {
descriptorConfig.encodeGeometry = true;
}
switch(descriptorType){
case 0:
desc = new KMLDescriptor<SearchEngine<EdgeData, StaticGraph<EdgeData> > >();
break;
case 1:
desc = new JSONDescriptor<SearchEngine<EdgeData, StaticGraph<EdgeData> > >();
break;
case 2:
desc = new GPXDescriptor<SearchEngine<EdgeData, StaticGraph<EdgeData> > >();
break;
default:
desc = new KMLDescriptor<SearchEngine<EdgeData, StaticGraph<EdgeData> > >();
break;
}
desc->SetConfig(descriptorConfig);
desc->Run(reply, rawRoute, phantomNodes, *sEngine, distance);
if("" != JSONParameter) {
reply.content += ")\n";
}
reply.headers.resize(3);
reply.headers[0].name = "Content-Length";
std::string tmp;
intToString(reply.content.size(), tmp);
reply.headers[0].value = tmp;
switch(descriptorType){
case 0:
reply.headers[1].name = "Content-Type";
reply.headers[1].value = "application/vnd.google-earth.kml+xml; charset=UTF-8";
reply.headers[2].name = "Content-Disposition";
reply.headers[2].value = "attachment; filename=\"route.kml\"";
break;
case 1:
if("" != JSONParameter){
reply.headers[1].name = "Content-Type";
reply.headers[1].value = "text/javascript";
reply.headers[2].name = "Content-Disposition";
reply.headers[2].value = "attachment; filename=\"route.js\"";
} else {
reply.headers[1].name = "Content-Type";
reply.headers[1].value = "application/x-javascript";
reply.headers[2].name = "Content-Disposition";
reply.headers[2].value = "attachment; filename=\"route.json\"";
}
break;
case 2:
reply.headers[1].name = "Content-Type";
reply.headers[1].value = "application/gpx+xml; charset=UTF-8";
reply.headers[2].name = "Content-Disposition";
reply.headers[2].value = "attachment; filename=\"route.gpx\"";
break;
default:
reply.headers[1].name = "Content-Type";
reply.headers[1].value = "application/vnd.google-earth.kml+xml; charset=UTF-8";
reply.headers[2].name = "Content-Disposition";
reply.headers[2].value = "attachment; filename=\"route.kml\"";
break;
}
DELETE( desc );
return;
}
private:
NodeInformationHelpDesk * nodeHelpDesk;
SearchEngine<EdgeData, StaticGraph<EdgeData> > *sEngine;
std::vector<std::string> * names;
StaticGraph<EdgeData> * graph;
HashTable<std::string, unsigned> descriptorTable;
std::string pluginDescriptorString;
};
#endif /* ROUTEPLUGIN_H_ */

View File

@ -33,7 +33,6 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "BasePlugin.h" #include "BasePlugin.h"
#include "RouteParameters.h" #include "RouteParameters.h"
#include "GPXDescriptor.h" #include "GPXDescriptor.h"
#include "KMLDescriptor.h"
#include "JSONDescriptor.h" #include "JSONDescriptor.h"
#include "../DataStructures/HashTable.h" #include "../DataStructures/HashTable.h"
@ -103,7 +102,7 @@ public:
} }
rawRoute.rawViaNodeCoordinates.push_back(startCoord); rawRoute.rawViaNodeCoordinates.push_back(startCoord);
// std::cout << "[debug] number of vianodes: " << routeParameters.viaPoints.size() << std::endl; INFO("[debug] number of vianodes: " << routeParameters.viaPoints.size());
for(unsigned i = 0; i < routeParameters.viaPoints.size(); i++) { for(unsigned i = 0; i < routeParameters.viaPoints.size(); i++) {
textCoord = split (routeParameters.viaPoints[i], ','); textCoord = split (routeParameters.viaPoints[i], ',');
if(textCoord.size() != 2) { if(textCoord.size() != 2) {
@ -112,7 +111,7 @@ public:
} }
int vialat = static_cast<int>(100000.*atof(textCoord[0].c_str())); int vialat = static_cast<int>(100000.*atof(textCoord[0].c_str()));
int vialon = static_cast<int>(100000.*atof(textCoord[1].c_str())); int vialon = static_cast<int>(100000.*atof(textCoord[1].c_str()));
// std::cout << "[debug] via" << i << ": " << vialat << "," << vialon << std::endl; INFO("[debug] via" << i << ": " << vialat << "," << vialon);
_Coordinate viaCoord(vialat, vialon); _Coordinate viaCoord(vialat, vialon);
if(false == checkCoord(viaCoord)) { if(false == checkCoord(viaCoord)) {
reply = http::Reply::stockReply(http::Reply::badRequest); reply = http::Reply::stockReply(http::Reply::badRequest);
@ -138,12 +137,13 @@ public:
PhantomNodes segmentPhantomNodes; PhantomNodes segmentPhantomNodes;
segmentPhantomNodes.startPhantom = phantomNodeVector[i]; segmentPhantomNodes.startPhantom = phantomNodeVector[i];
segmentPhantomNodes.targetPhantom = phantomNodeVector[i+1]; segmentPhantomNodes.targetPhantom = phantomNodeVector[i+1];
INFO(segmentPhantomNodes);
std::vector< _PathData > path; std::vector< _PathData > path;
unsigned distanceOfSegment = searchEngine->ComputeRoute(segmentPhantomNodes, path); unsigned distanceOfSegment = searchEngine->ComputeRoute(segmentPhantomNodes, path);
if(UINT_MAX == distanceOfSegment ) { if(UINT_MAX == distanceOfSegment ) {
errorOccurredFlag = true; errorOccurredFlag = true;
// cout << "Error occurred, path not found" << endl; INFO( "Error occurred, path not found" );
distance = UINT_MAX; distance = UINT_MAX;
break; break;
} else { } else {
@ -155,6 +155,8 @@ public:
rawRoute.routeSegments[i] = path; rawRoute.routeSegments[i] = path;
} }
INFO("Found path of length: " << distance);
reply.status = http::Reply::ok; reply.status = http::Reply::ok;
BaseDescriptor<SearchEngine<EdgeData, StaticGraph<EdgeData> > > * desc; BaseDescriptor<SearchEngine<EdgeData, StaticGraph<EdgeData> > > * desc;
@ -185,19 +187,15 @@ public:
switch(descriptorType){ switch(descriptorType){
case 0: case 0:
desc = new KMLDescriptor<SearchEngine<EdgeData, StaticGraph<EdgeData> > >();
break;
case 1:
desc = new JSONDescriptor<SearchEngine<EdgeData, StaticGraph<EdgeData> > >(); desc = new JSONDescriptor<SearchEngine<EdgeData, StaticGraph<EdgeData> > >();
break; break;
case 2: case 1:
desc = new GPXDescriptor<SearchEngine<EdgeData, StaticGraph<EdgeData> > >(); desc = new GPXDescriptor<SearchEngine<EdgeData, StaticGraph<EdgeData> > >();
break; break;
default: default:
desc = new KMLDescriptor<SearchEngine<EdgeData, StaticGraph<EdgeData> > >(); desc = new JSONDescriptor<SearchEngine<EdgeData, StaticGraph<EdgeData> > >();
break; break;
} }

View File

@ -122,21 +122,21 @@ NodeID readBinaryOSRMGraphFromStream(istream &in, vector<EdgeT>& edgeList, vecto
ExternalNodeMap::iterator intNodeID = ext2IntNodeMap.find(inputRestrictions[i].fromNode); ExternalNodeMap::iterator intNodeID = ext2IntNodeMap.find(inputRestrictions[i].fromNode);
if( intNodeID == ext2IntNodeMap.end()) { if( intNodeID == ext2IntNodeMap.end()) {
DEBUG("Unmapped restriction") DEBUG("Unmapped restriction")
continue; continue;
} }
inputRestrictions[i].fromNode = intNodeID->second; inputRestrictions[i].fromNode = intNodeID->second;
intNodeID = ext2IntNodeMap.find(inputRestrictions[i].viaNode); intNodeID = ext2IntNodeMap.find(inputRestrictions[i].viaNode);
if( intNodeID == ext2IntNodeMap.end()) { if( intNodeID == ext2IntNodeMap.end()) {
DEBUG("Unmapped restriction") DEBUG("Unmapped restriction")
continue; continue;
} }
inputRestrictions[i].viaNode = intNodeID->second; inputRestrictions[i].viaNode = intNodeID->second;
intNodeID = ext2IntNodeMap.find(inputRestrictions[i].toNode); intNodeID = ext2IntNodeMap.find(inputRestrictions[i].toNode);
if( intNodeID == ext2IntNodeMap.end()) { if( intNodeID == ext2IntNodeMap.end()) {
DEBUG("Unmapped restriction") DEBUG("Unmapped restriction")
continue; continue;
} }
inputRestrictions[i].toNode = intNodeID->second; inputRestrictions[i].toNode = intNodeID->second;
} }
@ -178,9 +178,9 @@ NodeID readBinaryOSRMGraphFromStream(istream &in, vector<EdgeT>& edgeList, vecto
intNodeID = ext2IntNodeMap.find(target); intNodeID = ext2IntNodeMap.find(target);
if(ext2IntNodeMap.find(target) == ext2IntNodeMap.end()) { if(ext2IntNodeMap.find(target) == ext2IntNodeMap.end()) {
#ifndef NDEBUG #ifndef NDEBUG
cerr << "unresolved target NodeID : " << target << endl; cerr << "unresolved target NodeID : " << target << endl;
#endif #endif
continue; continue;
} }
target = intNodeID->second; target = intNodeID->second;
@ -215,7 +215,7 @@ NodeID readDTMPGraphFromStream(istream &in, vector<EdgeT>& edgeList, vector<Node
EdgeWeight weight; EdgeWeight weight;
unsigned speedType(0); unsigned speedType(0);
short type(0); short type(0);
// NodeID nameID; // NodeID nameID;
int length; int length;
in >> source >> target >> length >> dir >> speedType; in >> source >> target >> length >> dir >> speedType;
@ -330,8 +330,8 @@ NodeID readDDSGGraphFromStream(istream &in, vector<EdgeT>& edgeList, vector<Node
EdgeWeight weight; EdgeWeight weight;
in >> source >> target >> weight >> dir; in >> source >> target >> weight >> dir;
// if(dir == 3) // if(dir == 3)
// dir = 0; // dir = 0;
assert(weight > 0); assert(weight > 0);
if(dir <0 || dir > 3) if(dir <0 || dir > 3)
@ -359,99 +359,44 @@ NodeID readDDSGGraphFromStream(istream &in, vector<EdgeT>& edgeList, vector<Node
} }
EdgeT inputEdge(source, target, 0, weight, forward, backward, 1 ); EdgeT inputEdge(source, target, 0, weight, forward, backward, 1 );
edgeList.push_back(inputEdge); edgeList.push_back(inputEdge);
} }
vector<EdgeT>(edgeList.begin(), edgeList.end()).swap(edgeList); //remove excess candidates. vector<EdgeT>(edgeList.begin(), edgeList.end()).swap(edgeList); //remove excess candidates.
// cout << "ok" << endl; // cout << "ok" << endl;
// std::cout << "imported " << numberOfNodes << " nodes and " << edgeList.size() << " edges" << std::endl; // std::cout << "imported " << numberOfNodes << " nodes and " << edgeList.size() << " edges" << std::endl;
nodeMap.clear(); nodeMap.clear();
return numberOfNodes; return numberOfNodes;
} }
template<typename EdgeT> template<typename EdgeT>
unsigned readHSGRFromStream(istream &in, vector<EdgeT> & edgeList) { unsigned readHSGRFromStream(istream &in, vector<EdgeT> & edgeList) {
unsigned numberOfNodes = 0; NodeID numberOfNodes = 0;
ExternalNodeMap nodeMap; do {
while(!in.eof()) {
EdgeT g; EdgeT g;
EdgeData e; EdgeData e;
int distance;
bool shortcut;
bool forward;
bool backward;
short type;
NodeID middle;
NodeID source; NodeID source;
NodeID target; NodeID target;
in.read((char *)&(distance), sizeof(int)); in.read((char *)&(e), sizeof(EdgeData));
assert(distance > 0); if(!in.good())
in.read((char *)&(shortcut), sizeof(bool)); break;
in.read((char *)&(forward), sizeof(bool)); assert(e.distance > 0);
in.read((char *)&(backward), sizeof(bool));
in.read((char *)&(middle), sizeof(NodeID));
in.read((char *)&(type), sizeof(short));
in.read((char *)&(source), sizeof(NodeID)); in.read((char *)&(source), sizeof(NodeID));
in.read((char *)&(target), sizeof(NodeID)); in.read((char *)&(target), sizeof(NodeID));
e.backward = backward; e.distance = distance; e.forward = forward; e.middleName.middle = middle; e.shortcut = shortcut; e.type = type;
g.data = e; g.data = e;
g.source = source; g.target = target; g.source = source; g.target = target;
if(source > numberOfNodes) if(source > numberOfNodes) {
numberOfNodes = source; numberOfNodes = source;
if(target > numberOfNodes) INFO("looked at source " << source);
}
if(target > numberOfNodes) {
numberOfNodes = target; numberOfNodes = target;
if(middle > numberOfNodes) }
numberOfNodes = middle;
edgeList.push_back(g); edgeList.push_back(g);
} } while(true);
return numberOfNodes+1; return numberOfNodes+1;
} }
template<typename EdgeT>
unsigned readHSGRFromStreamWithOutEdgeData(const char * hsgrName, vector<EdgeT> * edgeList) {
std::ifstream hsgrInStream(hsgrName, std::ios::binary);
unsigned numberOfNodes = 0;
ExternalNodeMap nodeMap;
while(!hsgrInStream.eof()) {
EdgeT g;
// EdgeData e;
int distance;
bool shortcut;
bool forward;
bool backward;
short type;
NodeID middle;
NodeID source;
NodeID target;
hsgrInStream.read((char *)&(distance), sizeof(int));
assert(distance > 0);
hsgrInStream.read((char *)&(shortcut), sizeof(bool));
hsgrInStream.read((char *)&(forward), sizeof(bool));
hsgrInStream.read((char *)&(backward), sizeof(bool));
hsgrInStream.read((char *)&(middle), sizeof(NodeID));
hsgrInStream.read((char *)&(type), sizeof(short));
hsgrInStream.read((char *)&(source), sizeof(NodeID));
hsgrInStream.read((char *)&(target), sizeof(NodeID));
g.data.backward = backward; g.data.distance = distance; g.data.forward = forward; g.data.shortcut = shortcut;
g.source = source; g.target = target;
if( nodeMap.find(source) == nodeMap.end()) {
nodeMap[numberOfNodes] = source;
numberOfNodes++;
}
if( nodeMap.find(target) == nodeMap.end()) {
nodeMap[numberOfNodes] = target;
numberOfNodes++;
}
edgeList->push_back(g);
}
hsgrInStream.close();
return numberOfNodes;
}
#endif // GRAPHLOADER_H #endif // GRAPHLOADER_H

View File

@ -72,10 +72,10 @@ std::string getFileAndLine (char * offset_end) {
void crashHandler(int sig_num, siginfo_t * info, void * ucontext) { void crashHandler(int sig_num, siginfo_t * info, void * ucontext) {
const size_t maxDepth = 100; const size_t maxDepth = 100;
size_t stackDepth; //size_t stackDepth;
void *stackAddrs[maxDepth]; void *stackAddrs[maxDepth];
stackDepth = backtrace(stackAddrs, maxDepth); backtrace(stackAddrs, maxDepth);
std::cerr << "signal " << sig_num << " (" << strsignal(sig_num) << "), address is " << info->si_addr << " from " << stackAddrs[0] << std::endl; std::cerr << "signal " << sig_num << " (" << strsignal(sig_num) << "), address is " << info->si_addr << " from " << stackAddrs[0] << std::endl;

View File

@ -42,7 +42,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
int omp_get_num_procs() { return 1; } int omp_get_num_procs() { return 1; }
int omp_get_max_threads() { return 1; } int omp_get_max_threads() { return 1; }
int omp_get_thread_num() { return 0; } int omp_get_thread_num() { return 0; }
int omp_set_num_threads(int i) {} void omp_set_num_threads(int i) {}
#endif #endif
#include "typedefs.h" #include "typedefs.h"
@ -67,23 +67,21 @@ vector<NodeInfo> int2ExtNodeMap;
vector<_Restriction> inputRestrictions; vector<_Restriction> inputRestrictions;
int main (int argc, char *argv[]) { int main (int argc, char *argv[]) {
if(argc <= 1) { if(argc < 3) {
cerr << "usage: " << endl << argv[0] << " <osrm-data>" << endl; cerr << "usage: " << endl << argv[0] << " <osrm-data> <osrm-restrictions>" << endl;
exit(-1); exit(-1);
} }
if(argc == 3) { INFO("Using restrictions from file: " << argv[2]);
INFO("Using restrictions from file: " << argv[2]); ifstream restrictionsInstream(argv[2], ios::binary);
ifstream restrictionsInstream(argv[2], ios::binary); _Restriction restriction;
_Restriction restriction; unsigned usableRestrictionsCounter(0);
unsigned usableRestrictionsCounter(0); restrictionsInstream.read((char*)&usableRestrictionsCounter, sizeof(unsigned));
restrictionsInstream.read((char*)&usableRestrictionsCounter, sizeof(unsigned)); for(unsigned i = 0; i < usableRestrictionsCounter; ++i) {
for(unsigned i = 0; i < usableRestrictionsCounter; ++i) { restrictionsInstream.read((char *)&(restriction), sizeof(_Restriction));
restrictionsInstream.read((char *)&(restriction), sizeof(_Restriction)); inputRestrictions.push_back(restriction);
inputRestrictions.push_back(restriction);
}
restrictionsInstream.close();
INFO("Loaded " << inputRestrictions.size() << " restrictions from file");
} }
restrictionsInstream.close();
INFO("Loaded " << inputRestrictions.size() << " restrictions from file");
unsigned numberOfThreads = omp_get_num_procs(); unsigned numberOfThreads = omp_get_num_procs();
if(testDataFile("contractor.ini")) { if(testDataFile("contractor.ini")) {
@ -106,22 +104,12 @@ int main (int argc, char *argv[]) {
cerr << "Cannot open " << argv[1] << endl; exit(-1); cerr << "Cannot open " << argv[1] << endl; exit(-1);
} }
vector<ImportEdge> edgeList;
NodeID n = readBinaryOSRMGraphFromStream(in, edgeList, &int2ExtNodeMap, inputRestrictions);
in.close();
EdgeBasedGraphFactory * edgeBasedGraphFactory = new EdgeBasedGraphFactory (n, edgeList, inputRestrictions);
edgeBasedGraphFactory->Run();
n = edgeBasedGraphFactory->GetNumberOfNodes();
std::vector<ImportEdge> edgeBasedEdgeList;
edgeBasedGraphFactory->GetEdges(edgeBasedEdgeList);
DELETE(edgeBasedGraphFactory);
char nodeOut[1024]; char nodeOut[1024];
char edgeOut[1024]; char edgeOut[1024];
char ramIndexOut[1024]; char ramIndexOut[1024];
char fileIndexOut[1024]; char fileIndexOut[1024];
char levelInfoOut[1024]; char levelInfoOut[1024];
strcpy(nodeOut, argv[1]); strcpy(nodeOut, argv[1]);
strcpy(edgeOut, argv[1]); strcpy(edgeOut, argv[1]);
strcpy(ramIndexOut, argv[1]); strcpy(ramIndexOut, argv[1]);
@ -134,6 +122,36 @@ int main (int argc, char *argv[]) {
strcat(fileIndexOut, ".fileIndex"); strcat(fileIndexOut, ".fileIndex");
strcat(levelInfoOut, ".levels"); strcat(levelInfoOut, ".levels");
vector<ImportEdge> edgeList;
NodeID n = readBinaryOSRMGraphFromStream(in, edgeList, &int2ExtNodeMap, inputRestrictions);
in.close();
EdgeBasedGraphFactory * edgeBasedGraphFactory = new EdgeBasedGraphFactory (n, edgeList, inputRestrictions, int2ExtNodeMap);
edgeBasedGraphFactory->Run();
n = edgeBasedGraphFactory->GetNumberOfNodes();
std::vector<EdgeBasedEdge> edgeBasedEdgeList;
edgeBasedGraphFactory->GetEdgeBasedEdges(edgeBasedEdgeList);
std::vector<EdgeBasedGraphFactory::EdgeBasedNode> nodeBasedEdgeList;
edgeBasedGraphFactory->GetEdgeBasedNodes(nodeBasedEdgeList);
INFO("size of nodeBasedEdgeList: " << nodeBasedEdgeList.size());
DELETE(edgeBasedGraphFactory);
WritableGrid * writeableGrid = new WritableGrid();
cout << "building grid ..." << flush;
writeableGrid->ConstructGrid(nodeBasedEdgeList, &int2ExtNodeMap, ramIndexOut, fileIndexOut);
delete writeableGrid;
std::cout << "writing node map ..." << std::flush;
ofstream mapOutFile(nodeOut, ios::binary);
for(NodeID i = 0; i < int2ExtNodeMap.size(); i++) {
mapOutFile.write((char *)&(int2ExtNodeMap.at(i)), sizeof(NodeInfo));
}
mapOutFile.close();
std::cout << "ok" << std::endl;
int2ExtNodeMap.clear();
cout << "initializing contractor ..." << flush; cout << "initializing contractor ..." << flush;
Contractor* contractor = new Contractor( n, edgeBasedEdgeList ); Contractor* contractor = new Contractor( n, edgeBasedEdgeList );
double contractionStartedTimestamp(get_timestamp()); double contractionStartedTimestamp(get_timestamp());
@ -164,7 +182,6 @@ int main (int argc, char *argv[]) {
levelOutFile.close(); levelOutFile.close();
std::vector< ContractionCleanup::Edge > contractedEdges; std::vector< ContractionCleanup::Edge > contractedEdges;
contractor->GetEdges( contractedEdges ); contractor->GetEdges( contractedEdges );
delete contractor;
ContractionCleanup * cleanup = new ContractionCleanup(n, contractedEdges); ContractionCleanup * cleanup = new ContractionCleanup(n, contractedEdges);
contractedEdges.clear(); contractedEdges.clear();
@ -179,50 +196,13 @@ int main (int argc, char *argv[]) {
Percent p(cleanedEdgeList.size()); Percent p(cleanedEdgeList.size());
for(std::vector< InputEdge>::iterator it = cleanedEdgeList.begin(); it != cleanedEdgeList.end(); it++) { for(std::vector< InputEdge>::iterator it = cleanedEdgeList.begin(); it != cleanedEdgeList.end(); it++) {
p.printIncrement(); p.printIncrement();
int distance= it->data.distance; edgeOutFile.write((char *)&(it->data), sizeof(EdgeData));
assert(distance > 0); edgeOutFile.write((char *)&(it->source), sizeof(NodeID));
bool shortcut= it->data.shortcut; edgeOutFile.write((char *)&(it->target), sizeof(NodeID));
bool forward= it->data.forward;
bool backward= it->data.backward;
NodeID middle;
if(shortcut)
middle = it->data.middleName.middle;
else {
middle = it->data.middleName.nameID;
}
NodeID source = it->source;
NodeID target = it->target;
short type = it->data.type;
edgeOutFile.write((char *)&(distance), sizeof(int));
edgeOutFile.write((char *)&(shortcut), sizeof(bool));
edgeOutFile.write((char *)&(forward), sizeof(bool));
edgeOutFile.write((char *)&(backward), sizeof(bool));
edgeOutFile.write((char *)&(middle), sizeof(NodeID));
edgeOutFile.write((char *)&(type), sizeof(short));
edgeOutFile.write((char *)&(source), sizeof(NodeID));
edgeOutFile.write((char *)&(target), sizeof(NodeID));
} }
edgeOutFile.close(); edgeOutFile.close();
cleanedEdgeList.clear(); cleanedEdgeList.clear();
std::cout << "writing node map ..." << std::flush;
ofstream mapOutFile(nodeOut, ios::binary);
for(NodeID i = 0; i < int2ExtNodeMap.size(); i++) {
mapOutFile.write((char *)&(int2ExtNodeMap.at(i)), sizeof(NodeInfo));
}
mapOutFile.close();
std::cout << "ok" << std::endl;
WritableGrid * writeableGrid = new WritableGrid();
cout << "building grid ..." << flush;
writeableGrid->ConstructGrid(edgeList, &int2ExtNodeMap, ramIndexOut, fileIndexOut);
delete writeableGrid;
int2ExtNodeMap.clear();
cout << "finished" << endl; cout << "finished" << endl;
return 0; return 0;
} }

View File

@ -443,7 +443,7 @@ int main (int argc, char *argv[]) {
fout.close(); fout.close();
cout << "ok" << endl; cout << "ok" << endl;
time = get_timestamp(); time = get_timestamp();
INFO("Written edges: " << usedEdgeCounter << " at " << positionInFile);
cout << "[extractor] writing street name index ... " << flush; cout << "[extractor] writing street name index ... " << flush;
vector<unsigned> * nameIndex = new vector<unsigned>(externalMemory.nameVector.size()+1, 0); vector<unsigned> * nameIndex = new vector<unsigned>(externalMemory.nameVector.size()+1, 0);
outputFileName.append(".names"); outputFileName.append(".names");

View File

@ -40,7 +40,6 @@ int omp_get_thread_num() { return 0; }
#include "Plugins/HelloWorldPlugin.h" #include "Plugins/HelloWorldPlugin.h"
#include "Plugins/LocatePlugin.h" #include "Plugins/LocatePlugin.h"
#include "Plugins/NearestPlugin.h" #include "Plugins/NearestPlugin.h"
#include "Plugins/RoutePlugin.h"
#include "Plugins/ViaRoutePlugin.h" #include "Plugins/ViaRoutePlugin.h"
#include "Util/InputFileUtil.h" #include "Util/InputFileUtil.h"
@ -110,8 +109,6 @@ int main (int argc, char *argv[]) {
h.RegisterPlugin(new NearestPlugin(objects)); h.RegisterPlugin(new NearestPlugin(objects));
h.RegisterPlugin(new RoutePlugin(objects));
h.RegisterPlugin(new ViaRoutePlugin(objects)); h.RegisterPlugin(new ViaRoutePlugin(objects));
boost::thread t(boost::bind(&Server::Run, s)); boost::thread t(boost::bind(&Server::Run, s));