First working edge based version. Still missing: GPX export; Via Points;
origin,destination on same edge, descriptions
This commit is contained in:
parent
34e4ead885
commit
97afa231ca
@ -62,10 +62,6 @@ private:
|
||||
delete _heapForward;
|
||||
}
|
||||
};
|
||||
union _MiddleName {
|
||||
NodeID nameID;
|
||||
NodeID middle;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
@ -73,12 +69,13 @@ public:
|
||||
NodeID source;
|
||||
NodeID target;
|
||||
struct EdgeData {
|
||||
int distance : 30;
|
||||
bool shortcut : 1;
|
||||
bool forward : 1;
|
||||
bool backward : 1;
|
||||
short type:7;
|
||||
_MiddleName middleName;
|
||||
NodeID via;
|
||||
unsigned nameID1;
|
||||
unsigned nameID2;
|
||||
int distance;
|
||||
bool shortcut;
|
||||
bool forward;
|
||||
bool backward;
|
||||
} data;
|
||||
|
||||
//sorts by source and other attributes
|
||||
@ -95,7 +92,10 @@ public:
|
||||
}
|
||||
|
||||
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
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -117,6 +117,7 @@ public:
|
||||
edge.data.shortcut = false;
|
||||
edge.data.nameID1 = i->nameID1();
|
||||
edge.data.nameID2 = i->nameID2();
|
||||
edge.data.via = i->via();
|
||||
edge.data.turnType = i->turnType();
|
||||
edge.data.forward = i->isForward();
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
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 >
|
||||
bool _CheckCH()
|
||||
{
|
||||
|
@ -32,12 +32,14 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#include <google/sparse_hash_map>
|
||||
#include <google/sparsetable>
|
||||
|
||||
template< typename NodeID, typename Key, bool initialize = true >
|
||||
template< typename NodeID, typename Key >
|
||||
class ArrayStorage {
|
||||
public:
|
||||
|
||||
ArrayStorage( size_t size )
|
||||
: positions( new Key[size] ) { if(initialize) { memset(positions, 0, size*sizeof(Key));} }
|
||||
ArrayStorage( size_t size ) : positions( new Key[size] ) {
|
||||
memset(positions, 0, size*sizeof(Key));
|
||||
INFO("initializing q for " << size << " elements");
|
||||
}
|
||||
|
||||
~ArrayStorage() {
|
||||
delete[] positions;
|
||||
@ -123,10 +125,6 @@ struct _SimpleHeapData {
|
||||
_SimpleHeapData( NodeID p ) : parent(p) { }
|
||||
};
|
||||
|
||||
//struct _NullHeapData {
|
||||
// _NullHeapData(NodeID p) {}
|
||||
//};
|
||||
|
||||
template < typename NodeID, typename Key, typename Weight, typename Data, typename IndexStorage = ArrayStorage<NodeID, NodeID> >
|
||||
class BinaryHeap {
|
||||
private:
|
||||
@ -144,7 +142,7 @@ public:
|
||||
void Clear() {
|
||||
heap.resize( 1 );
|
||||
insertedNodes.clear();
|
||||
heap[0].weight = (std::numeric_limits< Weight >::min)();
|
||||
heap[0].weight = std::numeric_limits< Weight >::min();
|
||||
nodeIndex.Clear();
|
||||
}
|
||||
|
||||
@ -215,7 +213,7 @@ public:
|
||||
assert( UINT_MAX != node );
|
||||
const Key index = nodeIndex[node];
|
||||
Key key = insertedNodes[index].key;
|
||||
assert ( key != 0 );
|
||||
assert ( key >= 0 );
|
||||
|
||||
insertedNodes[index].weight = weight;
|
||||
heap[key].weight = weight;
|
||||
|
@ -81,9 +81,7 @@ class DynamicGraph {
|
||||
}
|
||||
}
|
||||
|
||||
~DynamicGraph()
|
||||
{
|
||||
}
|
||||
~DynamicGraph(){ }
|
||||
|
||||
unsigned GetNumberOfNodes() const
|
||||
{
|
||||
|
@ -22,10 +22,9 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#define GRIDEDGE_H_
|
||||
|
||||
struct _GridEdge {
|
||||
_GridEdge(NodeID s, NodeID t, _Coordinate sc, _Coordinate tc) : start(s), target(t), startCoord(sc), targetCoord(tc) {}
|
||||
_GridEdge() : start(UINT_MAX), target(UINT_MAX) {}
|
||||
NodeID start;
|
||||
NodeID target;
|
||||
_GridEdge(NodeID n, _Coordinate sc, _Coordinate tc) : edgeBasedNode(n), startCoord(sc), targetCoord(tc) {}
|
||||
_GridEdge() : edgeBasedNode(UINT_MAX) {}
|
||||
NodeID edgeBasedNode;
|
||||
_Coordinate startCoord;
|
||||
_Coordinate targetCoord;
|
||||
};
|
||||
@ -37,14 +36,10 @@ struct GridEntry {
|
||||
unsigned fileIndex;
|
||||
unsigned ramIndex;
|
||||
bool operator< ( const GridEntry& right ) const {
|
||||
if(right.edge.start != edge.start)
|
||||
return right.edge.start < edge.start;
|
||||
if(right.edge.target != edge.target)
|
||||
return right.edge.target < edge.target;
|
||||
return false;
|
||||
return (edge.edgeBasedNode < right.edge.edgeBasedNode);
|
||||
}
|
||||
bool operator==( const GridEntry& right ) const {
|
||||
return right.edge.start == edge.start && right.edge.target == edge.target;
|
||||
return right.edge.edgeBasedNode == edge.edgeBasedNode;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -23,10 +23,10 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
|
||||
#include <cassert>
|
||||
|
||||
class Edge {
|
||||
class NodeBasedEdge {
|
||||
public:
|
||||
|
||||
bool operator< (const Edge& e) const {
|
||||
bool operator< (const NodeBasedEdge& e) const {
|
||||
if (source() == e.source()) {
|
||||
if (target() == e.target()) {
|
||||
if (weight() == e.weight()) {
|
||||
@ -41,10 +41,10 @@ public:
|
||||
}
|
||||
|
||||
/** Default constructor. target and weight are set to 0.*/
|
||||
Edge() :
|
||||
NodeBasedEdge() :
|
||||
_source(0), _target(0), _name(0), _weight(0), forward(0), backward(0), _type(0) { assert(false); } //shall not be used.
|
||||
|
||||
explicit Edge(NodeID s, NodeID t, NodeID n, EdgeWeight w, bool f, bool b, short ty) :
|
||||
explicit NodeBasedEdge(NodeID s, NodeID t, NodeID n, EdgeWeight w, bool f, bool b, short ty) :
|
||||
_source(s), _target(t), _name(n), _weight(w), forward(f), backward(b), _type(ty) { assert(ty >= 0); }
|
||||
|
||||
NodeID target() const {return _target; }
|
||||
@ -59,21 +59,79 @@ public:
|
||||
|
||||
NodeID _source;
|
||||
NodeID _target;
|
||||
NodeID _name:31;
|
||||
EdgeWeight _weight:31;
|
||||
bool forward:1;
|
||||
bool backward:1;
|
||||
NodeID _name;
|
||||
EdgeWeight _weight;
|
||||
bool forward;
|
||||
bool backward;
|
||||
short _type;
|
||||
};
|
||||
|
||||
struct MinimalEdgeData
|
||||
{
|
||||
class EdgeBasedEdge {
|
||||
public:
|
||||
|
||||
bool operator< (const EdgeBasedEdge& e) const {
|
||||
if (source() == e.source()) {
|
||||
if (target() == e.target()) {
|
||||
if (weight() == e.weight()) {
|
||||
return (isForward() && isBackward() &&
|
||||
((! e.isForward()) || (! e.isBackward())));
|
||||
}
|
||||
return (weight() < e.weight());
|
||||
}
|
||||
return (target() < e.target());
|
||||
}
|
||||
return (source() < e.source());
|
||||
}
|
||||
|
||||
template<class EdgeT>
|
||||
EdgeBasedEdge(const EdgeT & myEdge ) :
|
||||
_source(myEdge.source),
|
||||
_target(myEdge.target),
|
||||
_via(myEdge.data.via),
|
||||
_nameID1(myEdge.data.nameID1),
|
||||
_nameID2(myEdge.data.nameID2),
|
||||
_weight(myEdge.data.distance),
|
||||
forward(myEdge.data.forward),
|
||||
backward(myEdge.data.backward),
|
||||
_turnInstruction(myEdge.data.turnInstruction) { }
|
||||
|
||||
/** Default constructor. target and weight are set to 0.*/
|
||||
EdgeBasedEdge() :
|
||||
_source(0), _target(0), _via(0), _nameID1(0), _nameID2(0), _weight(0), forward(0), backward(0), _turnInstruction(0) { assert(false); } //shall not be used.
|
||||
|
||||
explicit EdgeBasedEdge(NodeID s, NodeID t, NodeID v, unsigned n1, unsigned n2, EdgeWeight w, bool f, bool b, short ty) :
|
||||
_source(s), _target(t), _via(v), _nameID1(n1), _nameID2(n2), _weight(w), forward(f), backward(b), _turnInstruction(ty) { assert(ty >= 0); }
|
||||
|
||||
NodeID target() const {return _target; }
|
||||
NodeID source() const {return _source; }
|
||||
EdgeWeight weight() const {return _weight; }
|
||||
NodeID via() const { return _via; }
|
||||
short turnType() const { assert(_turnInstruction >= 0); return _turnInstruction; }
|
||||
bool isBackward() const { return backward; }
|
||||
bool isForward() const { return forward; }
|
||||
|
||||
unsigned nameID1() const { return _nameID1; }
|
||||
unsigned nameID2() const { return _nameID2; }
|
||||
|
||||
NodeID _source;
|
||||
NodeID _target;
|
||||
NodeID _via;
|
||||
unsigned _nameID1;
|
||||
unsigned _nameID2;
|
||||
EdgeWeight _weight;
|
||||
bool forward;
|
||||
bool backward;
|
||||
short _turnInstruction;
|
||||
|
||||
};
|
||||
|
||||
struct MinimalEdgeData {
|
||||
public:
|
||||
EdgeWeight distance;
|
||||
bool forward;
|
||||
bool backward;
|
||||
};
|
||||
|
||||
typedef Edge ImportEdge;
|
||||
typedef NodeBasedEdge ImportEdge;
|
||||
|
||||
#endif // EDGE_H
|
||||
|
@ -37,6 +37,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#endif
|
||||
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <google/dense_hash_map>
|
||||
|
||||
#include "ExtractorStructs.h"
|
||||
@ -148,16 +149,6 @@ static void GetListOfIndexesForEdgeAndGridSize(_Coordinate& start, _Coordinate&
|
||||
|
||||
template<bool WriteAccess = false>
|
||||
class NNGrid {
|
||||
private:
|
||||
struct DiskEdge {
|
||||
NodeID start;
|
||||
NodeID target;
|
||||
int slat;
|
||||
int slon;
|
||||
int tlat;
|
||||
int tlon;
|
||||
};
|
||||
|
||||
public:
|
||||
NNGrid() : cellCache(500), fileCache(500) {
|
||||
ramIndexTable.resize((1024*1024), UINT_MAX);
|
||||
@ -167,6 +158,9 @@ public:
|
||||
}
|
||||
|
||||
NNGrid(const char* rif, const char* _i, unsigned numberOfThreads = omp_get_num_procs()): cellCache(500), fileCache(500) {
|
||||
if(WriteAccess) {
|
||||
ERR("Not available in Write mode");
|
||||
}
|
||||
iif = std::string(_i);
|
||||
ramIndexTable.resize((1024*1024), UINT_MAX);
|
||||
ramInFile.open(rif, std::ios::in | std::ios::binary);
|
||||
@ -183,7 +177,7 @@ public:
|
||||
void OpenIndexFiles() {
|
||||
assert(ramInFile.is_open());
|
||||
|
||||
for(int i = 0; i < 1024*1024; i++) {
|
||||
for(int i = 0; i < 1024*1024; ++i) {
|
||||
unsigned temp;
|
||||
ramInFile.read((char*)&temp, sizeof(unsigned));
|
||||
ramIndexTable[i] = temp;
|
||||
@ -194,19 +188,16 @@ public:
|
||||
template<typename EdgeT, typename NodeInfoT>
|
||||
void ConstructGrid(std::vector<EdgeT> & edgeList, vector<NodeInfoT> * int2ExtNodeMap, char * ramIndexOut, char * fileIndexOut) {
|
||||
Percent p(edgeList.size());
|
||||
for(NodeID i = 0; i < edgeList.size(); i++) {
|
||||
for(NodeID i = 0; i < edgeList.size(); ++i) {
|
||||
p.printIncrement();
|
||||
if( edgeList[i].isLocatable() == false )
|
||||
continue;
|
||||
EdgeT edge = edgeList[i];
|
||||
EdgeT & edge = edgeList[i];
|
||||
|
||||
int slat = 100000*lat2y(static_cast<double>(int2ExtNodeMap->at(edge.source()).lat)/100000.);
|
||||
int slon = int2ExtNodeMap->at(edge.source()).lon;
|
||||
int tlat = 100000*lat2y(static_cast<double>(int2ExtNodeMap->at(edge.target()).lat)/100000.);
|
||||
int tlon = int2ExtNodeMap->at(edge.target()).lon;
|
||||
int slat = 100000*lat2y(edge.lat1/100000.);
|
||||
int slon = edge.lon1;
|
||||
int tlat = 100000*lat2y(edge.lat2/100000.);
|
||||
int tlon = edge.lon2;
|
||||
AddEdge( _GridEdge(
|
||||
edgeList[i].source(),
|
||||
edgeList[i].target(),
|
||||
edge.id,
|
||||
_Coordinate(slat, slon),
|
||||
_Coordinate(tlat, tlon) )
|
||||
);
|
||||
@ -225,7 +216,7 @@ public:
|
||||
unsigned maxNumberOfRAMCellElements = 0;
|
||||
cout << "writing data ..." << flush;
|
||||
p.reinit(entries->size());
|
||||
for(stxxl::vector<GridEntry>::iterator vt = entries->begin(); vt != entries->end(); vt++) {
|
||||
for(stxxl::vector<GridEntry>::iterator vt = entries->begin(); vt != entries->end(); ++vt) {
|
||||
p.printIncrement();
|
||||
if(vt->ramIndex != indexInRamTable) {
|
||||
unsigned numberOfBytesInCell = FillCell(entriesInFileWithRAMSameIndex, lastPositionInIndexFile);
|
||||
@ -247,7 +238,7 @@ public:
|
||||
|
||||
assert(entriesInFileWithRAMSameIndex.size() == 0);
|
||||
|
||||
for(int i = 0; i < 1024*1024; i++) {
|
||||
for(int i = 0; i < 1024*1024; ++i) {
|
||||
if(ramIndexTable[i] != UINT_MAX) {
|
||||
numberOfUsedCells--;
|
||||
}
|
||||
@ -259,17 +250,17 @@ public:
|
||||
//Serialize RAM Index
|
||||
ofstream ramFile(ramIndexOut, std::ios::out | std::ios::binary | std::ios::trunc);
|
||||
//write 4 MB of index Table in RAM
|
||||
for(int i = 0; i < 1024*1024; i++)
|
||||
for(int i = 0; i < 1024*1024; ++i)
|
||||
ramFile.write((char *)&ramIndexTable[i], sizeof(unsigned) );
|
||||
//close ram index file
|
||||
ramFile.close();
|
||||
}
|
||||
|
||||
bool GetStartAndDestNodesOfEdge(const _Coordinate& coord, NodesOfEdge& nodesOfEdge) {
|
||||
bool GetEdgeBasedStartNode(const _Coordinate& coord, NodesOfEdge& nodesOfEdge) {
|
||||
_Coordinate startCoord(100000*(lat2y(static_cast<double>(coord.lat)/100000.)), coord.lon);
|
||||
/** search for point on edge next to source */
|
||||
unsigned fileIndex = GetFileIndexForLatLon(startCoord.lat, startCoord.lon);
|
||||
std::vector<_Edge> candidates;
|
||||
std::vector<_GridEdge> candidates;
|
||||
|
||||
for(int j = -32768; j < (32768+1); j+=32768) {
|
||||
for(int i = -1; i < 2; i++){
|
||||
@ -277,13 +268,12 @@ public:
|
||||
}
|
||||
}
|
||||
_Coordinate tmp;
|
||||
double dist = (numeric_limits<double>::max)();
|
||||
for(std::vector<_Edge>::iterator it = candidates.begin(); it != candidates.end(); it++) {
|
||||
double dist = numeric_limits<double>::max();
|
||||
BOOST_FOREACH(_GridEdge candidate, candidates) {
|
||||
double r = 0.;
|
||||
double tmpDist = ComputeDistance(startCoord, it->startCoord, it->targetCoord, tmp, &r);
|
||||
double tmpDist = ComputeDistance(startCoord, candidate.startCoord, candidate.targetCoord, tmp, &r);
|
||||
if(tmpDist < dist) {
|
||||
nodesOfEdge.startID = it->start;
|
||||
nodesOfEdge.destID = it->target;
|
||||
nodesOfEdge.edgeBasedNode = candidate.edgeBasedNode;
|
||||
nodesOfEdge.ratio = r;
|
||||
dist = tmpDist;
|
||||
nodesOfEdge.projectedPoint.lat = round(100000*(y2lat(static_cast<double>(tmp.lat)/100000.)));
|
||||
@ -297,11 +287,12 @@ public:
|
||||
}
|
||||
|
||||
bool FindPhantomNodeForCoordinate( const _Coordinate & location, PhantomNode & resultNode) {
|
||||
INFO("FindPhantomNodeForCoordinate");
|
||||
bool foundNode = false;
|
||||
_Coordinate startCoord(100000*(lat2y(static_cast<double>(location.lat)/100000.)), location.lon);
|
||||
/** search for point on edge close to source */
|
||||
unsigned fileIndex = GetFileIndexForLatLon(startCoord.lat, startCoord.lon);
|
||||
std::vector<_Edge> candidates;
|
||||
std::vector<_GridEdge> candidates;
|
||||
|
||||
for(int j = -32768; j < (32768+1); j+=32768) {
|
||||
for(int i = -1; i < 2; i++){
|
||||
@ -311,13 +302,16 @@ public:
|
||||
|
||||
_Coordinate tmp;
|
||||
double dist = (numeric_limits<double>::max)();
|
||||
for(std::vector<_Edge>::iterator it = candidates.begin(); it != candidates.end(); it++) {
|
||||
BOOST_FOREACH(_GridEdge candidate, candidates) {
|
||||
double r = 0.;
|
||||
double tmpDist = ComputeDistance(startCoord, it->startCoord, it->targetCoord, tmp, &r);
|
||||
double tmpDist = ComputeDistance(startCoord, candidate.startCoord, candidate.targetCoord, tmp, &r);
|
||||
if((tmpDist == dist) && 1 == std::abs((int)candidate.edgeBasedNode-(int)resultNode.edgeBasedNode)) {
|
||||
resultNode.isBidirected = true;
|
||||
resultNode.edgeBasedNode = std::min(candidate.edgeBasedNode, resultNode.edgeBasedNode);
|
||||
}
|
||||
if(tmpDist < dist) {
|
||||
// std::cout << "[debug] start distance " << (it - candidates.begin()) << " " << tmpDist << std::endl;
|
||||
resultNode.startNode = it->start;
|
||||
resultNode.targetNode = it->target;
|
||||
resultNode.isBidirected = false;
|
||||
resultNode.edgeBasedNode = candidate.edgeBasedNode;
|
||||
resultNode.ratio = r;
|
||||
dist = tmpDist;
|
||||
resultNode.location.lat = round(100000*(y2lat(static_cast<double>(tmp.lat)/100000.)));
|
||||
@ -334,9 +328,9 @@ public:
|
||||
FindPhantomNodeForCoordinate( target, routingStarts.targetPhantom) );
|
||||
}
|
||||
|
||||
void FindNearestNodeInGraph(const _Coordinate& inputCoordinate, _Coordinate& outputCoordinate) {
|
||||
void FindNearestCoordinateOnEdgeInNodeBasedGraph(const _Coordinate& inputCoordinate, _Coordinate& outputCoordinate) {
|
||||
unsigned fileIndex = GetFileIndexForLatLon(100000*(lat2y(static_cast<double>(inputCoordinate.lat)/100000.)), inputCoordinate.lon);
|
||||
std::vector<_Edge> candidates;
|
||||
std::vector<_GridEdge> candidates;
|
||||
for(int j = -32768; j < (32768+1); j+=32768) {
|
||||
for(int i = -1; i < 2; i++) {
|
||||
GetContentsOfFileBucket(fileIndex+i+j, candidates);
|
||||
@ -344,9 +338,9 @@ public:
|
||||
}
|
||||
_Coordinate tmp;
|
||||
double dist = (numeric_limits<double>::max)();
|
||||
for(std::vector<_Edge>::iterator it = candidates.begin(); it != candidates.end(); it++) {
|
||||
BOOST_FOREACH(_GridEdge candidate, candidates) {
|
||||
double r = 0.;
|
||||
double tmpDist = ComputeDistance(inputCoordinate, it->startCoord, it->targetCoord, tmp, &r);
|
||||
double tmpDist = ComputeDistance(inputCoordinate, candidate.startCoord, candidate.targetCoord, tmp, &r);
|
||||
if(tmpDist < dist) {
|
||||
dist = tmpDist;
|
||||
outputCoordinate = tmp;
|
||||
@ -359,7 +353,7 @@ public:
|
||||
_Coordinate startCoord(100000*(lat2y(static_cast<double>(inputCoordinate.lat)/100000.)), inputCoordinate.lon);
|
||||
unsigned fileIndex = GetFileIndexForLatLon(startCoord.lat, startCoord.lon);
|
||||
|
||||
std::vector<_Edge> candidates;
|
||||
std::vector<_GridEdge> candidates;
|
||||
for(int j = -32768; j < (32768+1); j+=32768) {
|
||||
for(int i = -1; i < 2; i++) {
|
||||
GetContentsOfFileBucket(fileIndex+i+j, candidates);
|
||||
@ -367,9 +361,9 @@ public:
|
||||
}
|
||||
_Coordinate tmp;
|
||||
double dist = (numeric_limits<double>::max)();
|
||||
for(std::vector<_Edge>::iterator it = candidates.begin(); it != candidates.end(); it++) {
|
||||
BOOST_FOREACH(_GridEdge candidate, candidates) {
|
||||
double r = 0.;
|
||||
double tmpDist = ComputeDistance(startCoord, it->startCoord, it->targetCoord, tmp, &r);
|
||||
double tmpDist = ComputeDistance(startCoord, candidate.startCoord, candidate.targetCoord, tmp, &r);
|
||||
if(tmpDist < dist) {
|
||||
dist = tmpDist;
|
||||
outputCoordinate.lat = round(100000*(y2lat(static_cast<double>(tmp.lat)/100000.)));
|
||||
@ -381,8 +375,7 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
unsigned FillCell(std::vector<GridEntry>& entriesWithSameRAMIndex, unsigned fileOffset )
|
||||
{
|
||||
unsigned FillCell(std::vector<GridEntry>& entriesWithSameRAMIndex, unsigned fileOffset ) {
|
||||
vector<char> * tmpBuffer = new vector<char>();
|
||||
tmpBuffer->resize(32*32*4096,0);
|
||||
unsigned indexIntoTmpBuffer = 0;
|
||||
@ -408,8 +401,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
for(unsigned i = 0; i < entriesWithSameRAMIndex.size() -1; i++)
|
||||
{
|
||||
for(unsigned i = 0; i < entriesWithSameRAMIndex.size() -1; ++i) {
|
||||
assert(entriesWithSameRAMIndex[i].ramIndex== entriesWithSameRAMIndex[i+1].ramIndex);
|
||||
}
|
||||
|
||||
@ -471,7 +463,7 @@ private:
|
||||
|
||||
unsigned FlushEntriesWithSameFileIndexToBuffer( std::vector<GridEntry> &vectorWithSameFileIndex, vector<char> * tmpBuffer, const unsigned index)
|
||||
{
|
||||
tmpBuffer->resize(tmpBuffer->size()+(sizeof(NodeID)+sizeof(NodeID)+4*sizeof(int)+sizeof(unsigned))*vectorWithSameFileIndex.size() );
|
||||
tmpBuffer->resize(tmpBuffer->size()+(sizeof(_GridEdge)*vectorWithSameFileIndex.size()) );
|
||||
unsigned counter = 0;
|
||||
unsigned max = UINT_MAX;
|
||||
|
||||
@ -482,44 +474,12 @@ private:
|
||||
}
|
||||
|
||||
sort( vectorWithSameFileIndex.begin(), vectorWithSameFileIndex.end() );
|
||||
std::vector<GridEntry>::const_iterator newEnd = unique(vectorWithSameFileIndex.begin(), vectorWithSameFileIndex.end());
|
||||
for(std::vector<GridEntry>::const_iterator et = vectorWithSameFileIndex.begin(); et != newEnd; et++)
|
||||
{
|
||||
char * start = (char *)&et->edge.start;
|
||||
for(unsigned i = 0; i < sizeof(NodeID); i++)
|
||||
{
|
||||
tmpBuffer->at(index+counter) = start[i];
|
||||
counter++;
|
||||
}
|
||||
char * target = (char *)&et->edge.target;
|
||||
for(unsigned i = 0; i < sizeof(NodeID); i++)
|
||||
{
|
||||
tmpBuffer->at(index+counter) = target[i];
|
||||
counter++;
|
||||
}
|
||||
char * slat = (char *) &(et->edge.startCoord.lat);
|
||||
for(unsigned i = 0; i < sizeof(int); i++)
|
||||
{
|
||||
tmpBuffer->at(index+counter) = slat[i];
|
||||
counter++;
|
||||
}
|
||||
char * slon = (char *) &(et->edge.startCoord.lon);
|
||||
for(unsigned i = 0; i < sizeof(int); i++)
|
||||
{
|
||||
tmpBuffer->at(index+counter) = slon[i];
|
||||
counter++;
|
||||
}
|
||||
char * tlat = (char *) &(et->edge.targetCoord.lat);
|
||||
for(unsigned i = 0; i < sizeof(int); i++)
|
||||
{
|
||||
tmpBuffer->at(index+counter) = tlat[i];
|
||||
counter++;
|
||||
}
|
||||
char * tlon = (char *) &(et->edge.targetCoord.lon);
|
||||
for(unsigned i = 0; i < sizeof(int); i++)
|
||||
{
|
||||
tmpBuffer->at(index+counter) = tlon[i];
|
||||
counter++;
|
||||
vectorWithSameFileIndex.erase(unique(vectorWithSameFileIndex.begin(), vectorWithSameFileIndex.end()), vectorWithSameFileIndex.end());
|
||||
BOOST_FOREACH(GridEntry entry, vectorWithSameFileIndex) {
|
||||
char * data = (char *)&(entry.edge);
|
||||
for(unsigned i = 0; i < sizeof(_GridEdge); ++i) {
|
||||
tmpBuffer->at(index+counter) = data[i];
|
||||
++counter;
|
||||
}
|
||||
}
|
||||
char * umax = (char *) &max;
|
||||
@ -531,7 +491,7 @@ private:
|
||||
return counter;
|
||||
}
|
||||
|
||||
void GetContentsOfFileBucket(const unsigned fileIndex, std::vector<_Edge>& result) {
|
||||
void GetContentsOfFileBucket(const unsigned fileIndex, std::vector<_GridEdge>& result) {
|
||||
unsigned ramIndex = GetRAMIndexFromFileIndex(fileIndex);
|
||||
unsigned startIndexInFile = ramIndexTable[ramIndex];
|
||||
if(startIndexInFile == UINT_MAX) {
|
||||
@ -569,19 +529,12 @@ private:
|
||||
|
||||
std::ifstream localStream(iif.c_str(), std::ios::in | std::ios::binary);
|
||||
localStream.seekg(position);
|
||||
DiskEdge diskEdge;
|
||||
_GridEdge gridEdge;
|
||||
do {
|
||||
localStream.read((char *)&(diskEdge), sizeof(DiskEdge));
|
||||
if(localStream.eof() || diskEdge.start == UINT_MAX)
|
||||
localStream.read((char *)&(gridEdge), sizeof(_GridEdge));
|
||||
if(localStream.eof() || gridEdge.edgeBasedNode == UINT_MAX)
|
||||
break;
|
||||
|
||||
_Edge e(diskEdge.start, diskEdge.target);
|
||||
e.startCoord.lat = diskEdge.slat;
|
||||
e.startCoord.lon = diskEdge.slon;
|
||||
e.targetCoord.lat = diskEdge.tlat;
|
||||
e.targetCoord.lon = diskEdge.tlon;
|
||||
|
||||
result.push_back(e);
|
||||
result.push_back(gridEdge);
|
||||
} while(true);
|
||||
localStream.close();
|
||||
|
||||
@ -590,7 +543,7 @@ private:
|
||||
void AddEdge(_GridEdge edge) {
|
||||
std::vector<std::pair<unsigned, unsigned> > indexList;
|
||||
GetListOfIndexesForEdgeAndGridSize(edge.startCoord, edge.targetCoord, indexList);
|
||||
for(unsigned i = 0; i < indexList.size(); i++) {
|
||||
for(unsigned i = 0; i < indexList.size(); ++i) {
|
||||
entries->push_back(GridEntry(edge, indexList[i].first, indexList[i].second));
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <limits>
|
||||
#include <climits>
|
||||
|
||||
#include "../typedefs.h"
|
||||
|
||||
@ -33,7 +33,7 @@ struct NodeCoords {
|
||||
typedef int value_type; //type of lat,lons
|
||||
|
||||
NodeCoords(int _lat, int _lon, NodeT _id) : lat(_lat), lon(_lon), id(_id) {}
|
||||
NodeCoords() : lat(UINT_MAX), lon(UINT_MAX), id(UINT_MAX) {}
|
||||
NodeCoords() : lat(INT_MAX), lon(INT_MAX), id(UINT_MAX) {}
|
||||
int lat;
|
||||
int lon;
|
||||
NodeT id;
|
||||
|
@ -31,27 +31,30 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
|
||||
class NodeInformationHelpDesk{
|
||||
public:
|
||||
NodeInformationHelpDesk(const char* ramIndexInput, const char* fileIndexInput) {
|
||||
NodeInformationHelpDesk(const char* ramIndexInput, const char* fileIndexInput, unsigned _numberOfNodes) : numberOfNodes(_numberOfNodes) {
|
||||
readOnlyGrid = new ReadOnlyGrid(ramIndexInput,fileIndexInput);
|
||||
int2ExtNodeMap = new vector<_Coordinate>();
|
||||
numberOfNodes = 0;
|
||||
int2ExtNodeMap->reserve(numberOfNodes);
|
||||
assert(0 == int2ExtNodeMap->size());
|
||||
}
|
||||
|
||||
~NodeInformationHelpDesk() {
|
||||
delete int2ExtNodeMap;
|
||||
delete readOnlyGrid;
|
||||
}
|
||||
void initNNGrid(ifstream& in) {
|
||||
while(!in.eof()) {
|
||||
while(!in.eof()) {
|
||||
NodeInfo b;
|
||||
in.read((char *)&b, sizeof(b));
|
||||
int2ExtNodeMap->push_back(_Coordinate(b.lat, b.lon));
|
||||
numberOfNodes++;
|
||||
}
|
||||
in.close();
|
||||
readOnlyGrid->OpenIndexFiles();
|
||||
}
|
||||
|
||||
inline int getLatitudeOfNode(const NodeID node) const { return int2ExtNodeMap->at(node).lat; }
|
||||
inline int getLatitudeOfNode(const NodeID node) const {
|
||||
return int2ExtNodeMap->at(node).lat;
|
||||
}
|
||||
|
||||
inline int getLongitudeOfNode(const NodeID node) const { return int2ExtNodeMap->at(node).lon; }
|
||||
|
||||
@ -59,7 +62,7 @@ public:
|
||||
NodeID getNumberOfNodes2() const { return int2ExtNodeMap->size(); }
|
||||
|
||||
inline void FindNearestNodeCoordForLatLon(const _Coordinate& coord, _Coordinate& result) {
|
||||
readOnlyGrid->FindNearestNodeInGraph(coord, result);
|
||||
readOnlyGrid->FindNearestCoordinateOnEdgeInNodeBasedGraph(coord, result);
|
||||
}
|
||||
bool FindPhantomNodeForCoordinate( const _Coordinate & location, PhantomNode & resultNode) {
|
||||
return readOnlyGrid->FindPhantomNodeForCoordinate(location, resultNode);
|
||||
@ -71,7 +74,7 @@ public:
|
||||
}
|
||||
|
||||
inline bool GetStartAndDestNodesOfEdge(const _Coordinate& coord, NodesOfEdge& nodesOfEdge) {
|
||||
return readOnlyGrid->GetStartAndDestNodesOfEdge(coord, nodesOfEdge);
|
||||
return readOnlyGrid->GetEdgeBasedStartNode(coord, nodesOfEdge);
|
||||
}
|
||||
|
||||
inline void FindNearestPointOnEdge(const _Coordinate & input, _Coordinate& output){
|
||||
|
@ -62,7 +62,7 @@ class PBFParser : public BaseParser<_Node, _RawRestrictionContainer, _Way> {
|
||||
|
||||
public:
|
||||
PBFParser(const char * fileName)
|
||||
: threadDataQueue( new concurrent_queue<_ThreadData*>(25) ) { /* Max 25 items in queue */
|
||||
: threadDataQueue( new ConcurrentQueue<_ThreadData*>(25) ) { /* Max 25 items in queue */
|
||||
GOOGLE_PROTOBUF_VERIFY_VERSION;
|
||||
input.open(fileName, std::ios::in | std::ios::binary);
|
||||
|
||||
@ -525,7 +525,7 @@ private:
|
||||
std::fstream input;
|
||||
|
||||
/* ThreadData Queue */
|
||||
concurrent_queue < _ThreadData* >* threadDataQueue;
|
||||
ConcurrentQueue < _ThreadData* >* threadDataQueue;
|
||||
};
|
||||
|
||||
#endif /* PBFPARSER_H_ */
|
||||
|
@ -24,15 +24,13 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#include "ExtractorStructs.h"
|
||||
|
||||
struct PhantomNode {
|
||||
PhantomNode() : startNode(UINT_MAX), targetNode(UINT_MAX), ratio(1.) {}
|
||||
|
||||
NodeID startNode;
|
||||
NodeID targetNode;
|
||||
PhantomNode() : isBidirected(false), edgeBasedNode(UINT_MAX), ratio(1.) {}
|
||||
bool isBidirected;
|
||||
NodeID edgeBasedNode;
|
||||
double ratio;
|
||||
_Coordinate location;
|
||||
void Reset() {
|
||||
startNode = UINT_MAX;
|
||||
targetNode = UINT_MAX;
|
||||
edgeBasedNode = UINT_MAX;
|
||||
ratio = 1.;
|
||||
location.Reset();
|
||||
}
|
||||
@ -47,28 +45,25 @@ struct PhantomNodes {
|
||||
targetPhantom.Reset();
|
||||
}
|
||||
|
||||
bool PhantomsAreOnSameEdge() const {
|
||||
return ((startPhantom.startNode == targetPhantom.startNode && startPhantom.targetNode == targetPhantom.targetNode ) || (startPhantom.startNode == targetPhantom.targetNode && targetPhantom.startNode == startPhantom.targetNode));
|
||||
bool PhantomsAreOnSameNodeBasedEdge() const {
|
||||
return (startPhantom.edgeBasedNode == targetPhantom.edgeBasedNode);
|
||||
}
|
||||
|
||||
bool AtLeastOnePhantomNodeIsUINTMAX() const {
|
||||
return !(startPhantom.startNode == UINT_MAX || startPhantom.targetNode == UINT_MAX || targetPhantom.startNode == UINT_MAX || targetPhantom.targetNode == UINT_MAX);
|
||||
return !(startPhantom.edgeBasedNode == UINT_MAX || targetPhantom.edgeBasedNode == UINT_MAX);
|
||||
}
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream &out, const PhantomNodes & pn){
|
||||
out << "startNode1: " << pn.startPhantom.startNode << std::endl;
|
||||
out << "startNode2: " << pn.startPhantom.targetNode << std::endl;
|
||||
out << "targetNode1: " << pn.targetPhantom.startNode << std::endl;
|
||||
out << "targetNode2: " << pn.targetPhantom.targetNode << std::endl;
|
||||
out << "Node1: " << pn.startPhantom.edgeBasedNode << std::endl;
|
||||
out << "Node2: " << pn.targetPhantom.edgeBasedNode << std::endl;
|
||||
out << "startCoord: " << pn.startPhantom.location << std::endl;
|
||||
out << "targetCoord: " << pn.targetPhantom.location << std::endl;
|
||||
return out;
|
||||
}
|
||||
|
||||
struct NodesOfEdge {
|
||||
NodeID startID;
|
||||
NodeID destID;
|
||||
NodeID edgeBasedNode;
|
||||
double ratio;
|
||||
_Coordinate projectedPoint;
|
||||
};
|
||||
|
@ -24,6 +24,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#include <climits>
|
||||
#include <deque>
|
||||
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
#include "BinaryHeap.h"
|
||||
#include "PhantomNodes.h"
|
||||
#include "../Util/StringUtil.h"
|
||||
@ -54,51 +56,22 @@ struct _Statistics {
|
||||
double preprocTime;
|
||||
};
|
||||
|
||||
struct _InsertedNodes {
|
||||
NodeID forward1;
|
||||
NodeID forward2;
|
||||
NodeID backward1;
|
||||
NodeID backward2;
|
||||
_InsertedNodes() : forward1(UINT_MAX), forward2(UINT_MAX), backward1(UINT_MAX), backward2(UINT_MAX) {};
|
||||
void BackInsert(NodeID n) {
|
||||
if(backward1 == UINT_MAX) {
|
||||
backward1 = n;
|
||||
} else {
|
||||
backward2 = n;
|
||||
}
|
||||
}
|
||||
void ForwInsert( NodeID n) {
|
||||
if(forward1 == UINT_MAX) {
|
||||
forward1 = n;
|
||||
} else {
|
||||
forward2 = n;
|
||||
}
|
||||
}
|
||||
typedef boost::thread_specific_ptr<BinaryHeap< NodeID, NodeID, int, _HeapData > > HeapPtr;
|
||||
|
||||
inline bool isForwardInserted(NodeID n) {
|
||||
return forward1 == n || forward2 == n;
|
||||
}
|
||||
|
||||
inline bool isBackwardInserted (NodeID n) {
|
||||
return backward1 == n || backward2 == n;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
typedef BinaryHeap< NodeID, int, int, _HeapData, ArrayStorage<NodeID, NodeID> > _Heap;
|
||||
|
||||
template<typename EdgeData, typename GraphT, typename NodeHelperT = NodeInformationHelpDesk>
|
||||
template<class EdgeData, class GraphT>
|
||||
class SearchEngine {
|
||||
private:
|
||||
const GraphT * _graph;
|
||||
NodeHelperT * nodeHelpDesk;
|
||||
const GraphT * _graph;
|
||||
NodeInformationHelpDesk * nodeHelpDesk;
|
||||
std::vector<string> * _names;
|
||||
static HeapPtr _forwardHeap;
|
||||
static HeapPtr _backwardHeap;
|
||||
inline double absDouble(double input) { if(input < 0) return input*(-1); else return input;}
|
||||
public:
|
||||
SearchEngine(GraphT * g, NodeHelperT * nh, vector<string> * n = new vector<string>()) : _graph(g), nodeHelpDesk(nh), _names(n) {}
|
||||
SearchEngine(GraphT * g, NodeInformationHelpDesk * nh, vector<string> * n = new vector<string>()) : _graph(g), nodeHelpDesk(nh), _names(n) {}
|
||||
~SearchEngine() {}
|
||||
|
||||
inline const void getCoordinatesForNodeID(NodeID id, _Coordinate& result) const {
|
||||
inline const void GetCoordinatesForNodeID(NodeID id, _Coordinate& result) const {
|
||||
result.lat = nodeHelpDesk->getLatitudeOfNode(id);
|
||||
result.lon = nodeHelpDesk->getLongitudeOfNode(id);
|
||||
}
|
||||
@ -107,246 +80,197 @@ public:
|
||||
return nodeHelpDesk->getNumberOfNodes();
|
||||
}
|
||||
|
||||
unsigned int ComputeRoute(PhantomNodes &phantomNodes, vector<_PathData > & path) {
|
||||
inline void InitializeThreadLocalStorageIfNecessary() {
|
||||
if(!_forwardHeap.get())
|
||||
_forwardHeap.reset(new BinaryHeap< NodeID, NodeID, int, _HeapData >(nodeHelpDesk->getNumberOfNodes()));
|
||||
else
|
||||
_forwardHeap->Clear();
|
||||
|
||||
bool startEdgeIsReversedInGraph = false;
|
||||
bool targetEdgeIsReversed = false;
|
||||
if(!_backwardHeap.get())
|
||||
_backwardHeap.reset(new BinaryHeap< NodeID, NodeID, int, _HeapData >(nodeHelpDesk->getNumberOfNodes()));
|
||||
else
|
||||
_backwardHeap->Clear();
|
||||
}
|
||||
|
||||
unsigned int _upperbound = UINT_MAX;
|
||||
unsigned int ComputeRoute(PhantomNodes & phantomNodes, vector<_PathData> & path) {
|
||||
unsigned int _upperbound = UINT_MAX;
|
||||
if(!phantomNodes.AtLeastOnePhantomNodeIsUINTMAX())
|
||||
return _upperbound;
|
||||
|
||||
if(!phantomNodes.AtLeastOnePhantomNodeIsUINTMAX())
|
||||
return _upperbound;
|
||||
InitializeThreadLocalStorageIfNecessary();
|
||||
NodeID middle = ( NodeID ) UINT_MAX;
|
||||
if(phantomNodes.PhantomsAreOnSameNodeBasedEdge()){
|
||||
//TODO: Hier behandeln, dass Start und Ziel auf der gleichen Originalkante liegen
|
||||
INFO("TODO: Start and target are on same edge")
|
||||
return _upperbound;
|
||||
}
|
||||
//insert start and/or target node of start edge
|
||||
_forwardHeap->Insert(phantomNodes.startPhantom.edgeBasedNode, 0, phantomNodes.startPhantom.edgeBasedNode);
|
||||
// INFO("Inserting start1: " << phantomNodes.startPhantom.edgeBasedNode);
|
||||
if(phantomNodes.startPhantom.isBidirected) {
|
||||
_forwardHeap->Insert(phantomNodes.startPhantom.edgeBasedNode+1, 0, phantomNodes.startPhantom.edgeBasedNode+1);
|
||||
// INFO("Inserting start2: " << phantomNodes.startPhantom.edgeBasedNode+1);
|
||||
}
|
||||
|
||||
EdgeID sourceEdgeID = _graph->FindEdgeIndicateIfReverse( phantomNodes.startPhantom.startNode, phantomNodes.startPhantom.targetNode, startEdgeIsReversedInGraph);
|
||||
if(sourceEdgeID == UINT_MAX){
|
||||
//insert start and/or target node of target edge id
|
||||
_backwardHeap->Insert(phantomNodes.targetPhantom.edgeBasedNode, 0, phantomNodes.targetPhantom.edgeBasedNode);
|
||||
// INFO("Inserting target1: " << phantomNodes.targetPhantom.edgeBasedNode);
|
||||
if(phantomNodes.targetPhantom.isBidirected) {
|
||||
_backwardHeap->Insert(phantomNodes.targetPhantom.edgeBasedNode+1, 0, phantomNodes.targetPhantom.edgeBasedNode+1);
|
||||
// INFO("Inserting target2: " << phantomNodes.targetPhantom.edgeBasedNode+1);
|
||||
}
|
||||
|
||||
while(_forwardHeap->Size() + _backwardHeap->Size() > 0){
|
||||
if(_forwardHeap->Size() > 0){
|
||||
_RoutingStep(_forwardHeap, _backwardHeap, true, &middle, &_upperbound);
|
||||
}
|
||||
if(_backwardHeap->Size() > 0){
|
||||
_RoutingStep(_backwardHeap, _forwardHeap, false, &middle, &_upperbound);
|
||||
}
|
||||
}
|
||||
// INFO("bidirectional search iteration ended: " << _forwardHeap->Size() << "," << _backwardHeap->Size() << ", dist: " << _upperbound);
|
||||
|
||||
if ( _upperbound == UINT_MAX ) {
|
||||
return _upperbound;
|
||||
}
|
||||
NodeID pathNode = middle;
|
||||
deque<NodeID> packedPath;
|
||||
while(phantomNodes.startPhantom.edgeBasedNode != pathNode && (!phantomNodes.startPhantom.isBidirected || phantomNodes.startPhantom.edgeBasedNode+1 != pathNode) ) {
|
||||
pathNode = _forwardHeap->GetData(pathNode).parent;
|
||||
packedPath.push_front(pathNode);
|
||||
}
|
||||
// INFO("Finished getting packed forward path: " << packedPath.size());
|
||||
packedPath.push_back(middle);
|
||||
pathNode = middle;
|
||||
while(phantomNodes.targetPhantom.edgeBasedNode != pathNode && (!phantomNodes.targetPhantom.isBidirected || phantomNodes.targetPhantom.edgeBasedNode+1 != pathNode)) {
|
||||
pathNode = _backwardHeap->GetData(pathNode).parent;
|
||||
packedPath.push_back(pathNode);
|
||||
}
|
||||
// INFO("Finished getting packed path: " << packedPath.size());
|
||||
for(deque<NodeID>::size_type i = 0;i < packedPath.size() - 1;i++){
|
||||
_UnpackEdge(packedPath[i], packedPath[i + 1], path);
|
||||
}
|
||||
return _upperbound;
|
||||
}
|
||||
|
||||
EdgeID targetEdgeID = _graph->FindEdgeIndicateIfReverse( phantomNodes.targetPhantom.startNode, phantomNodes.targetPhantom.targetNode, targetEdgeIsReversed);
|
||||
if(targetEdgeID == UINT_MAX){
|
||||
return _upperbound;
|
||||
}
|
||||
unsigned int ComputeDistanceBetweenNodes(NodeID start, NodeID target) {
|
||||
InitializeThreadLocalStorageIfNecessary();
|
||||
NodeID middle(UINT_MAX);
|
||||
unsigned int _upperbound = UINT_MAX;
|
||||
_forwardHeap->Insert(start, 0, start);
|
||||
_backwardHeap->Insert(target, 0, target);
|
||||
while(_forwardHeap->Size() + _backwardHeap->Size() > 0){
|
||||
if(_forwardHeap->Size() > 0){
|
||||
_RoutingStep(_forwardHeap, _backwardHeap, true, &middle, &_upperbound);
|
||||
}
|
||||
if(_backwardHeap->Size() > 0){
|
||||
_RoutingStep(_backwardHeap, _forwardHeap, false, &middle, &_upperbound);
|
||||
}
|
||||
}
|
||||
|
||||
_InsertedNodes _insertedNodes;
|
||||
return _upperbound;
|
||||
}
|
||||
|
||||
_Heap _forwardHeap(nodeHelpDesk->getNumberOfNodes());
|
||||
_Heap _backwardHeap(nodeHelpDesk->getNumberOfNodes());
|
||||
unsigned int ComputeDistanceBetweenNodesWithStats(NodeID start, NodeID target, _Statistics & stats) {
|
||||
InitializeThreadLocalStorageIfNecessary();
|
||||
NodeID middle(UINT_MAX);
|
||||
unsigned int _upperbound = UINT_MAX;
|
||||
_forwardHeap->Insert(start, 0, start);
|
||||
_backwardHeap->Insert(target, 0, target);
|
||||
stats.insertedNodes += 2;
|
||||
while(_forwardHeap->Size() + _backwardHeap->Size() > 0){
|
||||
if(_forwardHeap->Size() > 0){
|
||||
_RoutingStepWithStats(_forwardHeap, _backwardHeap, true, &middle, &_upperbound, stats);
|
||||
}
|
||||
if(_backwardHeap->Size() > 0){
|
||||
_RoutingStepWithStats(_backwardHeap, _forwardHeap, false, &middle, &_upperbound, stats);
|
||||
}
|
||||
}
|
||||
|
||||
NodeID middle = ( NodeID ) UINT_MAX;
|
||||
return _upperbound;
|
||||
}
|
||||
|
||||
if( phantomNodes.PhantomsAreOnSameEdge() ) {
|
||||
const EdgeData& currentEdgeData = _graph->GetEdgeData(sourceEdgeID);
|
||||
EdgeWeight w = currentEdgeData.distance;
|
||||
inline unsigned int findNearestNodeForLatLon(const _Coordinate & coord, _Coordinate & result) const {
|
||||
nodeHelpDesk->FindNearestNodeCoordForLatLon(coord, result);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//check if target is reachable from start on same edge
|
||||
if(currentEdgeData.forward && currentEdgeData.backward) {
|
||||
_upperbound = absDouble( w*phantomNodes.targetPhantom.ratio);
|
||||
return _upperbound/10;
|
||||
} else {
|
||||
if((startEdgeIsReversedInGraph && (phantomNodes.startPhantom.ratio > phantomNodes.targetPhantom.ratio)) || (!startEdgeIsReversedInGraph && (phantomNodes.startPhantom.ratio < phantomNodes.targetPhantom.ratio))) {
|
||||
_backwardHeap.Insert(phantomNodes.startPhantom.startNode, absDouble( w*phantomNodes.startPhantom.ratio), phantomNodes.startPhantom.startNode);
|
||||
_insertedNodes.BackInsert(phantomNodes.startPhantom.startNode);
|
||||
_forwardHeap.Insert(phantomNodes.startPhantom.targetNode, absDouble( w-w*phantomNodes.startPhantom.ratio), phantomNodes.startPhantom.targetNode);
|
||||
_insertedNodes.ForwInsert(phantomNodes.startPhantom.targetNode);
|
||||
} else {
|
||||
_upperbound = absDouble( w*phantomNodes.targetPhantom.ratio);
|
||||
return _upperbound/10;
|
||||
}
|
||||
}
|
||||
}
|
||||
inline bool FindRoutingStarts(const _Coordinate & start, const _Coordinate & target, PhantomNodes & routingStarts) {
|
||||
nodeHelpDesk->FindRoutingStarts(start, target, routingStarts);
|
||||
return true;
|
||||
}
|
||||
|
||||
//insert start and/or target node of start edge
|
||||
const EdgeData& sourceEdgeData = _graph->GetEdgeData(sourceEdgeID);
|
||||
EdgeWeight sw = sourceEdgeData.distance;
|
||||
inline bool FindPhantomNodeForCoordinate(const _Coordinate & location, PhantomNode & result) {
|
||||
return nodeHelpDesk->FindPhantomNodeForCoordinate(location, result);
|
||||
}
|
||||
|
||||
if( (sourceEdgeData.backward && !startEdgeIsReversedInGraph) || (sourceEdgeData.forward && startEdgeIsReversedInGraph) ){
|
||||
_forwardHeap.Insert(phantomNodes.startPhantom.startNode, absDouble( sw*phantomNodes.startPhantom.ratio), phantomNodes.startPhantom.startNode);
|
||||
_insertedNodes.ForwInsert(phantomNodes.startPhantom.startNode);
|
||||
}
|
||||
if( (sourceEdgeData.backward && startEdgeIsReversedInGraph) || (sourceEdgeData.forward && !startEdgeIsReversedInGraph) ) {
|
||||
_forwardHeap.Insert(phantomNodes.startPhantom.targetNode, absDouble(sw-sw*phantomNodes.startPhantom.ratio), phantomNodes.startPhantom.targetNode);
|
||||
_insertedNodes.ForwInsert(phantomNodes.startPhantom.targetNode);
|
||||
}
|
||||
inline NodeID GetNameIDForOriginDestinationNodeID(NodeID s, NodeID t) const {
|
||||
//INFO("Getting nameID for s=" << s << " and t=" << t);
|
||||
if(s == t)
|
||||
return 0;
|
||||
|
||||
//insert start and/or target node of target edge id
|
||||
const EdgeData& targetEdgeData = _graph->GetEdgeData(targetEdgeID);
|
||||
EdgeWeight tw = targetEdgeData.distance;
|
||||
|
||||
if( (targetEdgeData.backward && !targetEdgeIsReversed) || (targetEdgeData.forward && targetEdgeIsReversed) ) {
|
||||
_backwardHeap.Insert(phantomNodes.targetPhantom.targetNode, absDouble( tw*phantomNodes.targetPhantom.ratio), phantomNodes.targetPhantom.targetNode);
|
||||
_insertedNodes.BackInsert(phantomNodes.targetPhantom.targetNode);
|
||||
}
|
||||
if( (targetEdgeData.backward && targetEdgeIsReversed) || (targetEdgeData.forward && !targetEdgeIsReversed) ) {
|
||||
_backwardHeap.Insert(phantomNodes.targetPhantom.startNode, absDouble(tw-tw*phantomNodes.targetPhantom.ratio), phantomNodes.targetPhantom.startNode);
|
||||
_insertedNodes.BackInsert(phantomNodes.targetPhantom.startNode);
|
||||
}
|
||||
|
||||
while(_forwardHeap.Size() + _backwardHeap.Size() > 0) {
|
||||
if ( _forwardHeap.Size() > 0 ) {
|
||||
_RoutingStep( _forwardHeap, _backwardHeap, true, &middle, &_upperbound );
|
||||
}
|
||||
if ( _backwardHeap.Size() > 0 ) {
|
||||
_RoutingStep( _backwardHeap, _forwardHeap, false, &middle, &_upperbound );
|
||||
}
|
||||
}
|
||||
|
||||
if ( _upperbound == UINT_MAX ) {
|
||||
return _upperbound;
|
||||
}
|
||||
|
||||
NodeID pathNode = middle;
|
||||
deque< NodeID > packedPath;
|
||||
|
||||
while ( false == _insertedNodes.isForwardInserted(pathNode) ) {
|
||||
pathNode = _forwardHeap.GetData( pathNode ).parent;
|
||||
packedPath.push_front( pathNode );
|
||||
}
|
||||
|
||||
packedPath.push_back( middle );
|
||||
pathNode = middle;
|
||||
|
||||
while ( false == _insertedNodes.isBackwardInserted(pathNode) ){
|
||||
pathNode = _backwardHeap.GetData( pathNode ).parent;
|
||||
packedPath.push_back( pathNode );
|
||||
}
|
||||
|
||||
path.push_back( _PathData(packedPath[0]) );
|
||||
for(deque<NodeID>::size_type i = 0; i < packedPath.size()-1; i++) {
|
||||
_UnpackEdge(packedPath[i], packedPath[i+1], path);
|
||||
}
|
||||
|
||||
packedPath.clear();
|
||||
return _upperbound/10;
|
||||
}
|
||||
|
||||
unsigned int ComputeDistanceBetweenNodes(NodeID start, NodeID target) {
|
||||
_Heap _forwardHeap(_graph->GetNumberOfNodes());
|
||||
_Heap _backwardHeap(_graph->GetNumberOfNodes());
|
||||
NodeID middle(UINT_MAX);
|
||||
unsigned int _upperbound = UINT_MAX;
|
||||
|
||||
_forwardHeap.Insert(start, 0, start);
|
||||
_backwardHeap.Insert(target, 0, target);
|
||||
|
||||
while(_forwardHeap.Size() + _backwardHeap.Size() > 0) {
|
||||
if ( _forwardHeap.Size() > 0 ) {
|
||||
_RoutingStep( _forwardHeap, _backwardHeap, true, &middle, &_upperbound );
|
||||
}
|
||||
if ( _backwardHeap.Size() > 0 ) {
|
||||
_RoutingStep( _backwardHeap, _forwardHeap, false, &middle, &_upperbound );
|
||||
}
|
||||
}
|
||||
return _upperbound;
|
||||
}
|
||||
|
||||
unsigned int ComputeDistanceBetweenNodesWithStats(NodeID start, NodeID target, _Statistics& stats) {
|
||||
_Heap _forwardHeap(_graph->GetNumberOfNodes());
|
||||
_Heap _backwardHeap(_graph->GetNumberOfNodes());
|
||||
NodeID middle(UINT_MAX);
|
||||
unsigned int _upperbound = UINT_MAX;
|
||||
|
||||
_forwardHeap.Insert(start, 0, start);
|
||||
_backwardHeap.Insert(target, 0, target);
|
||||
stats.insertedNodes += 2;
|
||||
|
||||
while(_forwardHeap.Size() + _backwardHeap.Size() > 0) {
|
||||
if ( _forwardHeap.Size() > 0 ) {
|
||||
_RoutingStepWithStats( _forwardHeap, _backwardHeap, true, &middle, &_upperbound, stats );
|
||||
}
|
||||
if ( _backwardHeap.Size() > 0 ) {
|
||||
_RoutingStepWithStats( _backwardHeap, _forwardHeap, false, &middle, &_upperbound, stats );
|
||||
}
|
||||
}
|
||||
return _upperbound;
|
||||
}
|
||||
|
||||
inline unsigned int findNearestNodeForLatLon(const _Coordinate& coord, _Coordinate& result) const
|
||||
{
|
||||
nodeHelpDesk->findNearestNodeCoordForLatLon( coord, result );
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
inline bool FindRoutingStarts(const _Coordinate &start, const _Coordinate &target, PhantomNodes & routingStarts) {
|
||||
nodeHelpDesk->FindRoutingStarts(start, target, routingStarts);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool FindPhantomNodeForCoordinate(const _Coordinate &location, PhantomNode & result) {
|
||||
return nodeHelpDesk->FindPhantomNodeForCoordinate(location, result);
|
||||
}
|
||||
|
||||
inline NodeID GetNameIDForOriginDestinationNodeID(NodeID s, NodeID t) const {
|
||||
//INFO("Getting nameID for s=" << s << " and t=" << t);
|
||||
if(s==t)
|
||||
return 0;
|
||||
EdgeID e = _graph->FindEdge( s, t );
|
||||
if(e == UINT_MAX)
|
||||
EdgeID e = _graph->FindEdge(s, t);
|
||||
if(e == UINT_MAX)
|
||||
e = _graph->FindEdge( t, s );
|
||||
if(UINT_MAX == e) {
|
||||
if(UINT_MAX == e) {
|
||||
// INFO("edge not found for start " << s << ", target " << t)
|
||||
return 0;
|
||||
}
|
||||
assert(e != UINT_MAX);
|
||||
const EdgeData ed = _graph->GetEdgeData(e);
|
||||
return ed.middleName.nameID;
|
||||
}
|
||||
assert(e != UINT_MAX);
|
||||
const EdgeData ed = _graph->GetEdgeData(e);
|
||||
return ed.via;
|
||||
}
|
||||
|
||||
inline NodeID GetWeightForOriginDestinationNodeID(NodeID s, NodeID t) const {
|
||||
assert(s!=t);
|
||||
EdgeID e = _graph->FindEdge( s, t );
|
||||
if(e == UINT_MAX)
|
||||
inline NodeID GetWeightForOriginDestinationNodeID(NodeID s, NodeID t) const {
|
||||
assert(s!=t);
|
||||
EdgeID e = _graph->FindEdge(s, t);
|
||||
if(e == UINT_MAX)
|
||||
e = _graph->FindEdge( t, s );
|
||||
assert(e != UINT_MAX);
|
||||
const EdgeData ed = _graph->GetEdgeData(e);
|
||||
return ed.distance;
|
||||
}
|
||||
assert(e != UINT_MAX);
|
||||
const EdgeData ed = _graph->GetEdgeData(e);
|
||||
return ed.distance;
|
||||
}
|
||||
|
||||
inline std::string &GetUnescapedNameForNameID(const NodeID nameID) const {
|
||||
return (nameID >= _names->size() ? _names->at(0) : _names->at(nameID) );
|
||||
}
|
||||
inline std::string & GetUnescapedNameForNameID(const NodeID nameID) const {
|
||||
return (nameID >= _names->size() ? _names->at(0) : _names->at(nameID));
|
||||
}
|
||||
|
||||
inline std::string GetEscapedNameForOriginDestinationNodeID(NodeID s, NodeID t) const {
|
||||
NodeID nameID = GetNameIDForOriginDestinationNodeID(s, t);
|
||||
return ( GetEscapedNameForNameID(nameID) );
|
||||
}
|
||||
inline std::string GetEscapedNameForOriginDestinationNodeID(NodeID s, NodeID t) const {
|
||||
NodeID nameID = GetNameIDForOriginDestinationNodeID(s, t);
|
||||
return (GetEscapedNameForNameID(nameID));
|
||||
}
|
||||
|
||||
inline std::string GetEscapedNameForNameID(const NodeID nameID) const {
|
||||
return ( (nameID >= _names->size() || nameID == 0) ? std::string("") : HTMLEntitize(_names->at(nameID)) );
|
||||
}
|
||||
inline std::string GetEscapedNameForNameID(const NodeID nameID) const {
|
||||
return ((nameID >= _names->size() || nameID == 0) ? std::string("") : HTMLEntitize(_names->at(nameID)));
|
||||
}
|
||||
|
||||
inline short GetTypeOfEdgeForOriginDestinationNodeID(NodeID s, NodeID t) const {
|
||||
assert(s!=t);
|
||||
EdgeID e = _graph->FindEdge( s, t );
|
||||
if(e == UINT_MAX)
|
||||
inline short GetTypeOfEdgeForOriginDestinationNodeID(NodeID s, NodeID t) const {
|
||||
assert(s!=t);
|
||||
EdgeID e = _graph->FindEdge(s, t);
|
||||
if(e == UINT_MAX)
|
||||
e = _graph->FindEdge( t, s );
|
||||
assert(e != UINT_MAX);
|
||||
const EdgeData ed = _graph->GetEdgeData(e);
|
||||
return ed.type;
|
||||
}
|
||||
assert(e != UINT_MAX);
|
||||
const EdgeData ed = _graph->GetEdgeData(e);
|
||||
return ed.type;
|
||||
}
|
||||
|
||||
// inline void RegisterThread(const unsigned k, const unsigned v) {
|
||||
// nodeHelpDesk->RegisterThread(k,v);
|
||||
// }
|
||||
private:
|
||||
inline void _RoutingStep(HeapPtr & _forwardHeap, HeapPtr & _backwardHeap, const bool & forwardDirection, NodeID *middle, unsigned int *_upperbound) {
|
||||
const NodeID node = _forwardHeap->DeleteMin();
|
||||
const unsigned int distance = _forwardHeap->GetKey(node);
|
||||
if(_backwardHeap->WasInserted(node)){
|
||||
const unsigned int newDistance = _backwardHeap->GetKey(node) + distance;
|
||||
if(newDistance < *_upperbound){
|
||||
*middle = node;
|
||||
*_upperbound = newDistance;
|
||||
}
|
||||
}
|
||||
|
||||
inline void _RoutingStep(_Heap& _forwardHeap, _Heap &_backwardHeap, const bool& forwardDirection, NodeID * middle, unsigned int * _upperbound) {
|
||||
const NodeID node = _forwardHeap.DeleteMin();
|
||||
const unsigned int distance = _forwardHeap.GetKey( node );
|
||||
if ( _backwardHeap.WasInserted( node ) ) {
|
||||
const unsigned int newDistance = _backwardHeap.GetKey( node ) + distance;
|
||||
if ( newDistance < *_upperbound ) {
|
||||
*middle = node;
|
||||
*_upperbound = newDistance;
|
||||
}
|
||||
}
|
||||
if ( distance > *_upperbound ) {
|
||||
_forwardHeap.DeleteAll();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
for ( typename GraphT::EdgeIterator edge = _graph->BeginEdges( node ); edge < _graph->EndEdges(node); edge++ ) {
|
||||
if(distance > *_upperbound){
|
||||
_forwardHeap->DeleteAll();
|
||||
return;
|
||||
}
|
||||
/* for ( typename GraphT::EdgeIterator edge = _graph->BeginEdges( node ); edge < _graph->EndEdges(node); edge++ ) {
|
||||
const NodeID to = _graph->GetTarget(edge);
|
||||
const EdgeWeight edgeWeight = _graph->GetEdgeData(edge).distance;
|
||||
|
||||
@ -354,57 +278,57 @@ private:
|
||||
|
||||
//Stalling
|
||||
bool backwardDirectionFlag = (!forwardDirection) ? _graph->GetEdgeData(edge).forward : _graph->GetEdgeData(edge).backward;
|
||||
if(_forwardHeap.WasInserted( to )) {
|
||||
if(_forwardHeap->WasInserted( to )) {
|
||||
if(backwardDirectionFlag) {
|
||||
if(_forwardHeap.GetKey( to ) + edgeWeight < distance) {
|
||||
if(_forwardHeap->GetKey( to ) + edgeWeight < distance) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for ( typename GraphT::EdgeIterator edge = _graph->BeginEdges( node ); edge < _graph->EndEdges(node); edge++ ) {
|
||||
*/
|
||||
for ( typename GraphT::EdgeIterator edge = _graph->BeginEdges( node ); edge < _graph->EndEdges(node); edge++ ) {
|
||||
const NodeID to = _graph->GetTarget(edge);
|
||||
const EdgeWeight edgeWeight = _graph->GetEdgeData(edge).distance;
|
||||
|
||||
assert( edgeWeight > 0 );
|
||||
const int toDistance = distance + edgeWeight;
|
||||
|
||||
assert(toDistance > 0);
|
||||
|
||||
bool forwardDirectionFlag = (forwardDirection ? _graph->GetEdgeData(edge).forward : _graph->GetEdgeData(edge).backward );
|
||||
if(forwardDirectionFlag) {
|
||||
//New Node discovered -> Add to Heap + Node Info Storage
|
||||
if ( !_forwardHeap.WasInserted( to ) ) {
|
||||
_forwardHeap.Insert( to, toDistance, node );
|
||||
if ( !_forwardHeap->WasInserted( to ) ) {
|
||||
_forwardHeap->Insert( to, toDistance, node );
|
||||
}
|
||||
//Found a shorter Path -> Update distance
|
||||
else if ( toDistance < _forwardHeap.GetKey( to ) ) {
|
||||
_forwardHeap.GetData( to ).parent = node;
|
||||
_forwardHeap.DecreaseKey( to, toDistance );
|
||||
else if ( toDistance < _forwardHeap->GetKey( to ) ) {
|
||||
_forwardHeap->GetData( to ).parent = node;
|
||||
_forwardHeap->DecreaseKey( to, toDistance );
|
||||
//new parent
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void _RoutingStepWithStats( _Heap& _forwardHeap, _Heap &_backwardHeap, const bool& forwardDirection, NodeID * middle, unsigned int * _upperbound, _Statistics& stats) {
|
||||
const NodeID node = _forwardHeap.DeleteMin();
|
||||
stats.deleteMins++;
|
||||
const unsigned int distance = _forwardHeap.GetKey( node );
|
||||
if ( _backwardHeap.WasInserted( node ) ) {
|
||||
const unsigned int newDistance = _backwardHeap.GetKey( node ) + distance;
|
||||
if ( newDistance < *_upperbound ) {
|
||||
*middle = node;
|
||||
*_upperbound = newDistance;
|
||||
}
|
||||
}
|
||||
if ( distance > *_upperbound ) {
|
||||
stats.meetingNodes++;
|
||||
_forwardHeap.DeleteAll();
|
||||
return;
|
||||
}
|
||||
inline void _RoutingStepWithStats(HeapPtr & _forwardHeap, HeapPtr & _backwardHeap, const bool & forwardDirection, NodeID *middle, unsigned int *_upperbound, _Statistics & stats) {
|
||||
const NodeID node = _forwardHeap->DeleteMin();
|
||||
stats.deleteMins++;
|
||||
const unsigned int distance = _forwardHeap->GetKey(node);
|
||||
if(_backwardHeap->WasInserted(node)){
|
||||
const unsigned int newDistance = _backwardHeap->GetKey(node) + distance;
|
||||
if(newDistance < *_upperbound){
|
||||
*middle = node;
|
||||
*_upperbound = newDistance;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for ( typename GraphT::EdgeIterator edge = _graph->BeginEdges( node ); edge < _graph->EndEdges(node); edge++ ) {
|
||||
if(distance > *_upperbound) {
|
||||
stats.meetingNodes++;
|
||||
_forwardHeap->DeleteAll();
|
||||
return;
|
||||
}
|
||||
for ( typename GraphT::EdgeIterator edge = _graph->BeginEdges( node ); edge < _graph->EndEdges(node); edge++ ) {
|
||||
const EdgeData& ed = _graph->GetEdgeData(edge);
|
||||
const NodeID to = _graph->GetTarget(edge);
|
||||
const EdgeWeight edgeWeight = ed.distance;
|
||||
@ -413,9 +337,9 @@ private:
|
||||
const int toDistance = distance + edgeWeight;
|
||||
|
||||
//Stalling
|
||||
if(_forwardHeap.WasInserted( to )) {
|
||||
if(_forwardHeap->WasInserted( to )) {
|
||||
if(!forwardDirection ? ed.forward : ed.backward) {
|
||||
if(_forwardHeap.GetKey( to ) + edgeWeight < distance) {
|
||||
if(_forwardHeap->GetKey( to ) + edgeWeight < distance) {
|
||||
stats.stalledNodes++;
|
||||
return;
|
||||
}
|
||||
@ -424,57 +348,62 @@ private:
|
||||
|
||||
if(forwardDirection ? ed.forward : ed.backward ) {
|
||||
//New Node discovered -> Add to Heap + Node Info Storage
|
||||
if ( !_forwardHeap.WasInserted( to ) ) {
|
||||
_forwardHeap.Insert( to, toDistance, node );
|
||||
if ( !_forwardHeap->WasInserted( to ) ) {
|
||||
_forwardHeap->Insert( to, toDistance, node );
|
||||
stats.insertedNodes++;
|
||||
}
|
||||
//Found a shorter Path -> Update distance
|
||||
else if ( toDistance < _forwardHeap.GetKey( to ) ) {
|
||||
_forwardHeap.GetData( to ).parent = node;
|
||||
_forwardHeap.DecreaseKey( to, toDistance );
|
||||
else if ( toDistance < _forwardHeap->GetKey( to ) ) {
|
||||
_forwardHeap->GetData( to ).parent = node;
|
||||
_forwardHeap->DecreaseKey( to, toDistance );
|
||||
stats.decreasedNodes++;
|
||||
//new parent
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline bool _UnpackEdge( const NodeID source, const NodeID target, std::vector< _PathData >& path ) {
|
||||
assert(source != target);
|
||||
//find edge first.
|
||||
bool forward = true;
|
||||
typename GraphT::EdgeIterator smallestEdge = SPECIAL_EDGEID;
|
||||
EdgeWeight smallestWeight = UINT_MAX;
|
||||
for(typename GraphT::EdgeIterator eit = _graph->BeginEdges(source); eit < _graph->EndEdges(source); eit++) {
|
||||
const EdgeWeight weight = _graph->GetEdgeData(eit).distance;
|
||||
if(_graph->GetTarget(eit) == target && weight < smallestWeight && _graph->GetEdgeData(eit).forward) {
|
||||
smallestEdge = eit; smallestWeight = weight;
|
||||
}
|
||||
}
|
||||
if(smallestEdge == SPECIAL_EDGEID) {
|
||||
for(typename GraphT::EdgeIterator eit = _graph->BeginEdges(target); eit < _graph->EndEdges(target); eit++) {
|
||||
const EdgeWeight weight = _graph->GetEdgeData(eit).distance;
|
||||
if(_graph->GetTarget(eit) == source && weight < smallestWeight && _graph->GetEdgeData(eit).backward) {
|
||||
smallestEdge = eit; smallestWeight = weight;
|
||||
forward = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
inline bool _UnpackEdge(const NodeID source, const NodeID target, std::vector<_PathData> & path) {
|
||||
assert(source != target);
|
||||
//find edge first.
|
||||
typename GraphT::EdgeIterator smallestEdge = SPECIAL_EDGEID;
|
||||
EdgeWeight smallestWeight = UINT_MAX;
|
||||
for(typename GraphT::EdgeIterator eit = _graph->BeginEdges(source);eit < _graph->EndEdges(source);eit++){
|
||||
const EdgeWeight weight = _graph->GetEdgeData(eit).distance;
|
||||
if(_graph->GetTarget(eit) == target && weight < smallestWeight && _graph->GetEdgeData(eit).forward){
|
||||
smallestEdge = eit;
|
||||
smallestWeight = weight;
|
||||
}
|
||||
}
|
||||
|
||||
assert(smallestWeight != SPECIAL_EDGEID); //no edge found. This should not happen at all!
|
||||
if(smallestEdge == SPECIAL_EDGEID){
|
||||
for(typename GraphT::EdgeIterator eit = _graph->BeginEdges(target);eit < _graph->EndEdges(target);eit++){
|
||||
const EdgeWeight weight = _graph->GetEdgeData(eit).distance;
|
||||
if(_graph->GetTarget(eit) == source && weight < smallestWeight && _graph->GetEdgeData(eit).backward){
|
||||
smallestEdge = eit;
|
||||
smallestWeight = weight;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
assert(smallestWeight != SPECIAL_EDGEID);
|
||||
|
||||
const EdgeData& ed = _graph->GetEdgeData(smallestEdge);
|
||||
// INFO( (ed.shortcut ? "SHRT: " : "ORIG: ") << ed.distance << "," << ed.via);
|
||||
if(ed.shortcut) {//unpack
|
||||
const NodeID middle = ed.middleName.middle;
|
||||
const NodeID middle = ed.via;
|
||||
_UnpackEdge(source, middle, path);
|
||||
_UnpackEdge(middle, target, path);
|
||||
return false;
|
||||
} else {
|
||||
assert(!ed.shortcut);
|
||||
path.push_back(_PathData(target) );
|
||||
path.push_back(_PathData(ed.via) );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
template<class EdgeData, class GraphT> HeapPtr SearchEngine<EdgeData, GraphT>::_forwardHeap;
|
||||
template<class EdgeData, class GraphT> HeapPtr SearchEngine<EdgeData, GraphT>::_backwardHeap;
|
||||
|
||||
#endif /* SEARCHENGINE_H_ */
|
||||
|
@ -49,7 +49,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
StaticGraph( int nodes, std::vector< InputEdge > &graph ) {
|
||||
StaticGraph( const int nodes, std::vector< InputEdge > &graph ) {
|
||||
#ifdef _GLIBCXX_PARALLEL
|
||||
__gnu_parallel::sort( graph.begin(), graph.end() );
|
||||
#else
|
||||
@ -62,9 +62,8 @@ public:
|
||||
EdgeIterator position = 0;
|
||||
for ( NodeIterator node = 0; node <= _numNodes; ++node ) {
|
||||
EdgeIterator lastEdge = edge;
|
||||
while ( edge < _numEdges && graph[edge].source == node ) {
|
||||
while ( edge < _numEdges && graph[edge].source == node )
|
||||
++edge;
|
||||
}
|
||||
_nodes[node].firstEdge = position; //=edge
|
||||
position += edge - lastEdge; //remove
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ public:
|
||||
if( ! path.size() )
|
||||
continue;
|
||||
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);
|
||||
reply.content += "<rtept lat=\"" + tmp + "\" ";
|
||||
|
@ -21,6 +21,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#ifndef JSON_DESCRIPTOR_H_
|
||||
#define JSON_DESCRIPTOR_H_
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include "BaseDescriptor.h"
|
||||
#include "../DataStructures/PolylineCompressor.h"
|
||||
|
||||
@ -48,143 +50,18 @@ public:
|
||||
|
||||
//Put first segment of route into geometry
|
||||
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++) {
|
||||
const std::vector< _PathData > & path = rawRoute.routeSegments[segmentIdx];
|
||||
if(path.empty())
|
||||
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);
|
||||
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;
|
||||
}
|
||||
BOOST_FOREACH(_PathData pathData, path) {
|
||||
_Coordinate current;
|
||||
sEngine.GetCoordinatesForNodeID(pathData.node, current);
|
||||
polyline.push_back(current);
|
||||
// INFO(pathData.node << " at " << current.lat << "," << current.lon);
|
||||
//INFO("routed over node: " << pathData.node);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
descriptorState.geometryCounter++;
|
||||
appendInstructionLengthToString(descriptorState.distanceOfInstruction, descriptorState.routeInstructionString);
|
||||
summary.BuildDurationAndLengthStrings(descriptorState.entireDistance, distance);
|
||||
|
||||
} else {
|
||||
//no route found
|
||||
reply.content += "207,"
|
||||
|
@ -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 += " 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_ */
|
@ -28,28 +28,30 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#include "../DataStructures/StaticGraph.h"
|
||||
#include "../Util/GraphLoader.h"
|
||||
|
||||
typedef StaticGraph<EdgeData> QueryGraph;
|
||||
typedef QueryGraph::InputEdge InputEdge;
|
||||
|
||||
struct ObjectsForQueryStruct {
|
||||
typedef StaticGraph<EdgeData> QueryGraph;
|
||||
typedef QueryGraph::InputEdge InputEdge;
|
||||
|
||||
NodeInformationHelpDesk * nodeHelpDesk;
|
||||
std::vector<std::string> * names;
|
||||
QueryGraph * graph;
|
||||
|
||||
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;
|
||||
//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);
|
||||
//Deserialize road network graph
|
||||
std::vector< InputEdge> edgeList;
|
||||
readHSGRFromStream(hsgrInStream, edgeList);
|
||||
graph = new QueryGraph(nodeHelpDesk->getNumberOfNodes()-1, edgeList);
|
||||
const int n = readHSGRFromStream(hsgrInStream, edgeList);
|
||||
INFO("Graph has " << n << " nodes");
|
||||
graph = new QueryGraph(n, edgeList);
|
||||
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
|
||||
ifstream namesInStream(namesPath.c_str(), ios::binary);
|
||||
unsigned size(0);
|
||||
|
@ -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_ */
|
@ -33,7 +33,6 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#include "BasePlugin.h"
|
||||
#include "RouteParameters.h"
|
||||
#include "GPXDescriptor.h"
|
||||
#include "KMLDescriptor.h"
|
||||
#include "JSONDescriptor.h"
|
||||
|
||||
#include "../DataStructures/HashTable.h"
|
||||
@ -103,7 +102,7 @@ public:
|
||||
}
|
||||
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++) {
|
||||
textCoord = split (routeParameters.viaPoints[i], ',');
|
||||
if(textCoord.size() != 2) {
|
||||
@ -112,7 +111,7 @@ public:
|
||||
}
|
||||
int vialat = static_cast<int>(100000.*atof(textCoord[0].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);
|
||||
if(false == checkCoord(viaCoord)) {
|
||||
reply = http::Reply::stockReply(http::Reply::badRequest);
|
||||
@ -138,12 +137,13 @@ public:
|
||||
PhantomNodes segmentPhantomNodes;
|
||||
segmentPhantomNodes.startPhantom = phantomNodeVector[i];
|
||||
segmentPhantomNodes.targetPhantom = phantomNodeVector[i+1];
|
||||
INFO(segmentPhantomNodes);
|
||||
std::vector< _PathData > path;
|
||||
unsigned distanceOfSegment = searchEngine->ComputeRoute(segmentPhantomNodes, path);
|
||||
|
||||
if(UINT_MAX == distanceOfSegment ) {
|
||||
errorOccurredFlag = true;
|
||||
// cout << "Error occurred, path not found" << endl;
|
||||
INFO( "Error occurred, path not found" );
|
||||
distance = UINT_MAX;
|
||||
break;
|
||||
} else {
|
||||
@ -155,6 +155,8 @@ public:
|
||||
rawRoute.routeSegments[i] = path;
|
||||
}
|
||||
|
||||
INFO("Found path of length: " << distance);
|
||||
|
||||
reply.status = http::Reply::ok;
|
||||
|
||||
BaseDescriptor<SearchEngine<EdgeData, StaticGraph<EdgeData> > > * desc;
|
||||
@ -185,19 +187,15 @@ public:
|
||||
|
||||
switch(descriptorType){
|
||||
case 0:
|
||||
desc = new KMLDescriptor<SearchEngine<EdgeData, StaticGraph<EdgeData> > >();
|
||||
|
||||
break;
|
||||
case 1:
|
||||
desc = new JSONDescriptor<SearchEngine<EdgeData, StaticGraph<EdgeData> > >();
|
||||
|
||||
break;
|
||||
case 2:
|
||||
case 1:
|
||||
desc = new GPXDescriptor<SearchEngine<EdgeData, StaticGraph<EdgeData> > >();
|
||||
|
||||
break;
|
||||
default:
|
||||
desc = new KMLDescriptor<SearchEngine<EdgeData, StaticGraph<EdgeData> > >();
|
||||
desc = new JSONDescriptor<SearchEngine<EdgeData, StaticGraph<EdgeData> > >();
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -122,21 +122,21 @@ NodeID readBinaryOSRMGraphFromStream(istream &in, vector<EdgeT>& edgeList, vecto
|
||||
ExternalNodeMap::iterator intNodeID = ext2IntNodeMap.find(inputRestrictions[i].fromNode);
|
||||
if( intNodeID == ext2IntNodeMap.end()) {
|
||||
DEBUG("Unmapped restriction")
|
||||
continue;
|
||||
continue;
|
||||
}
|
||||
inputRestrictions[i].fromNode = intNodeID->second;
|
||||
|
||||
intNodeID = ext2IntNodeMap.find(inputRestrictions[i].viaNode);
|
||||
if( intNodeID == ext2IntNodeMap.end()) {
|
||||
DEBUG("Unmapped restriction")
|
||||
continue;
|
||||
continue;
|
||||
}
|
||||
inputRestrictions[i].viaNode = intNodeID->second;
|
||||
|
||||
intNodeID = ext2IntNodeMap.find(inputRestrictions[i].toNode);
|
||||
if( intNodeID == ext2IntNodeMap.end()) {
|
||||
DEBUG("Unmapped restriction")
|
||||
continue;
|
||||
continue;
|
||||
}
|
||||
inputRestrictions[i].toNode = intNodeID->second;
|
||||
}
|
||||
@ -178,9 +178,9 @@ NodeID readBinaryOSRMGraphFromStream(istream &in, vector<EdgeT>& edgeList, vecto
|
||||
intNodeID = ext2IntNodeMap.find(target);
|
||||
if(ext2IntNodeMap.find(target) == ext2IntNodeMap.end()) {
|
||||
#ifndef NDEBUG
|
||||
cerr << "unresolved target NodeID : " << target << endl;
|
||||
cerr << "unresolved target NodeID : " << target << endl;
|
||||
#endif
|
||||
continue;
|
||||
continue;
|
||||
}
|
||||
target = intNodeID->second;
|
||||
|
||||
@ -215,7 +215,7 @@ NodeID readDTMPGraphFromStream(istream &in, vector<EdgeT>& edgeList, vector<Node
|
||||
EdgeWeight weight;
|
||||
unsigned speedType(0);
|
||||
short type(0);
|
||||
// NodeID nameID;
|
||||
// NodeID nameID;
|
||||
int length;
|
||||
in >> source >> target >> length >> dir >> speedType;
|
||||
|
||||
@ -330,8 +330,8 @@ NodeID readDDSGGraphFromStream(istream &in, vector<EdgeT>& edgeList, vector<Node
|
||||
EdgeWeight weight;
|
||||
in >> source >> target >> weight >> dir;
|
||||
|
||||
// if(dir == 3)
|
||||
// dir = 0;
|
||||
// if(dir == 3)
|
||||
// dir = 0;
|
||||
|
||||
assert(weight > 0);
|
||||
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 );
|
||||
edgeList.push_back(inputEdge);
|
||||
}
|
||||
}
|
||||
vector<EdgeT>(edgeList.begin(), edgeList.end()).swap(edgeList); //remove excess candidates.
|
||||
|
||||
// cout << "ok" << endl;
|
||||
// std::cout << "imported " << numberOfNodes << " nodes and " << edgeList.size() << " edges" << std::endl;
|
||||
// cout << "ok" << endl;
|
||||
// std::cout << "imported " << numberOfNodes << " nodes and " << edgeList.size() << " edges" << std::endl;
|
||||
nodeMap.clear();
|
||||
return numberOfNodes;
|
||||
}
|
||||
|
||||
template<typename EdgeT>
|
||||
unsigned readHSGRFromStream(istream &in, vector<EdgeT> & edgeList) {
|
||||
unsigned numberOfNodes = 0;
|
||||
ExternalNodeMap nodeMap;
|
||||
while(!in.eof()) {
|
||||
NodeID numberOfNodes = 0;
|
||||
do {
|
||||
EdgeT g;
|
||||
EdgeData e;
|
||||
|
||||
int distance;
|
||||
bool shortcut;
|
||||
bool forward;
|
||||
bool backward;
|
||||
short type;
|
||||
NodeID middle;
|
||||
NodeID source;
|
||||
NodeID target;
|
||||
|
||||
in.read((char *)&(distance), sizeof(int));
|
||||
assert(distance > 0);
|
||||
in.read((char *)&(shortcut), sizeof(bool));
|
||||
in.read((char *)&(forward), sizeof(bool));
|
||||
in.read((char *)&(backward), sizeof(bool));
|
||||
in.read((char *)&(middle), sizeof(NodeID));
|
||||
in.read((char *)&(type), sizeof(short));
|
||||
in.read((char *)&(e), sizeof(EdgeData));
|
||||
if(!in.good())
|
||||
break;
|
||||
assert(e.distance > 0);
|
||||
in.read((char *)&(source), 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.source = source; g.target = target;
|
||||
|
||||
if(source > numberOfNodes)
|
||||
if(source > numberOfNodes) {
|
||||
numberOfNodes = source;
|
||||
if(target > numberOfNodes)
|
||||
INFO("looked at source " << source);
|
||||
}
|
||||
if(target > numberOfNodes) {
|
||||
numberOfNodes = target;
|
||||
if(middle > numberOfNodes)
|
||||
numberOfNodes = middle;
|
||||
|
||||
}
|
||||
edgeList.push_back(g);
|
||||
}
|
||||
} while(true);
|
||||
|
||||
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
|
||||
|
@ -72,10 +72,10 @@ std::string getFileAndLine (char * offset_end) {
|
||||
|
||||
void crashHandler(int sig_num, siginfo_t * info, void * ucontext) {
|
||||
const size_t maxDepth = 100;
|
||||
size_t stackDepth;
|
||||
//size_t stackDepth;
|
||||
|
||||
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;
|
||||
|
||||
|
@ -42,7 +42,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
int omp_get_num_procs() { return 1; }
|
||||
int omp_get_max_threads() { return 1; }
|
||||
int omp_get_thread_num() { return 0; }
|
||||
int omp_set_num_threads(int i) {}
|
||||
void omp_set_num_threads(int i) {}
|
||||
#endif
|
||||
|
||||
#include "typedefs.h"
|
||||
@ -67,23 +67,21 @@ vector<NodeInfo> int2ExtNodeMap;
|
||||
vector<_Restriction> inputRestrictions;
|
||||
|
||||
int main (int argc, char *argv[]) {
|
||||
if(argc <= 1) {
|
||||
cerr << "usage: " << endl << argv[0] << " <osrm-data>" << endl;
|
||||
if(argc < 3) {
|
||||
cerr << "usage: " << endl << argv[0] << " <osrm-data> <osrm-restrictions>" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
if(argc == 3) {
|
||||
INFO("Using restrictions from file: " << argv[2]);
|
||||
ifstream restrictionsInstream(argv[2], ios::binary);
|
||||
_Restriction restriction;
|
||||
unsigned usableRestrictionsCounter(0);
|
||||
restrictionsInstream.read((char*)&usableRestrictionsCounter, sizeof(unsigned));
|
||||
for(unsigned i = 0; i < usableRestrictionsCounter; ++i) {
|
||||
restrictionsInstream.read((char *)&(restriction), sizeof(_Restriction));
|
||||
inputRestrictions.push_back(restriction);
|
||||
}
|
||||
restrictionsInstream.close();
|
||||
INFO("Loaded " << inputRestrictions.size() << " restrictions from file");
|
||||
INFO("Using restrictions from file: " << argv[2]);
|
||||
ifstream restrictionsInstream(argv[2], ios::binary);
|
||||
_Restriction restriction;
|
||||
unsigned usableRestrictionsCounter(0);
|
||||
restrictionsInstream.read((char*)&usableRestrictionsCounter, sizeof(unsigned));
|
||||
for(unsigned i = 0; i < usableRestrictionsCounter; ++i) {
|
||||
restrictionsInstream.read((char *)&(restriction), sizeof(_Restriction));
|
||||
inputRestrictions.push_back(restriction);
|
||||
}
|
||||
restrictionsInstream.close();
|
||||
INFO("Loaded " << inputRestrictions.size() << " restrictions from file");
|
||||
|
||||
unsigned numberOfThreads = omp_get_num_procs();
|
||||
if(testDataFile("contractor.ini")) {
|
||||
@ -106,22 +104,12 @@ int main (int argc, char *argv[]) {
|
||||
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 edgeOut[1024];
|
||||
char ramIndexOut[1024];
|
||||
char fileIndexOut[1024];
|
||||
char levelInfoOut[1024];
|
||||
|
||||
strcpy(nodeOut, argv[1]);
|
||||
strcpy(edgeOut, argv[1]);
|
||||
strcpy(ramIndexOut, argv[1]);
|
||||
@ -134,6 +122,36 @@ int main (int argc, char *argv[]) {
|
||||
strcat(fileIndexOut, ".fileIndex");
|
||||
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;
|
||||
Contractor* contractor = new Contractor( n, edgeBasedEdgeList );
|
||||
double contractionStartedTimestamp(get_timestamp());
|
||||
@ -164,7 +182,6 @@ int main (int argc, char *argv[]) {
|
||||
levelOutFile.close();
|
||||
std::vector< ContractionCleanup::Edge > contractedEdges;
|
||||
contractor->GetEdges( contractedEdges );
|
||||
delete contractor;
|
||||
|
||||
ContractionCleanup * cleanup = new ContractionCleanup(n, contractedEdges);
|
||||
contractedEdges.clear();
|
||||
@ -179,50 +196,13 @@ int main (int argc, char *argv[]) {
|
||||
Percent p(cleanedEdgeList.size());
|
||||
for(std::vector< InputEdge>::iterator it = cleanedEdgeList.begin(); it != cleanedEdgeList.end(); it++) {
|
||||
p.printIncrement();
|
||||
int distance= it->data.distance;
|
||||
assert(distance > 0);
|
||||
bool shortcut= it->data.shortcut;
|
||||
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.write((char *)&(it->data), sizeof(EdgeData));
|
||||
edgeOutFile.write((char *)&(it->source), sizeof(NodeID));
|
||||
edgeOutFile.write((char *)&(it->target), sizeof(NodeID));
|
||||
}
|
||||
edgeOutFile.close();
|
||||
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;
|
||||
return 0;
|
||||
}
|
||||
|
@ -443,7 +443,7 @@ int main (int argc, char *argv[]) {
|
||||
fout.close();
|
||||
cout << "ok" << endl;
|
||||
time = get_timestamp();
|
||||
|
||||
INFO("Written edges: " << usedEdgeCounter << " at " << positionInFile);
|
||||
cout << "[extractor] writing street name index ... " << flush;
|
||||
vector<unsigned> * nameIndex = new vector<unsigned>(externalMemory.nameVector.size()+1, 0);
|
||||
outputFileName.append(".names");
|
||||
|
@ -40,7 +40,6 @@ int omp_get_thread_num() { return 0; }
|
||||
#include "Plugins/HelloWorldPlugin.h"
|
||||
#include "Plugins/LocatePlugin.h"
|
||||
#include "Plugins/NearestPlugin.h"
|
||||
#include "Plugins/RoutePlugin.h"
|
||||
#include "Plugins/ViaRoutePlugin.h"
|
||||
#include "Util/InputFileUtil.h"
|
||||
|
||||
@ -110,8 +109,6 @@ int main (int argc, char *argv[]) {
|
||||
|
||||
h.RegisterPlugin(new NearestPlugin(objects));
|
||||
|
||||
h.RegisterPlugin(new RoutePlugin(objects));
|
||||
|
||||
h.RegisterPlugin(new ViaRoutePlugin(objects));
|
||||
|
||||
boost::thread t(boost::bind(&Server::Run, s));
|
||||
|
Loading…
Reference in New Issue
Block a user