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

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

View File

@ -62,10 +62,6 @@ private:
delete _heapForward;
}
};
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
);
}
};

View File

@ -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()
{

View File

@ -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;

View File

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

View File

@ -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;
}
};

View File

@ -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

View File

@ -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));
}
}

View File

@ -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;

View File

@ -31,11 +31,13 @@ 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;
@ -45,13 +47,14 @@ public:
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){

View File

@ -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_ */

View File

@ -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;
};

View File

@ -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;
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,180 +80,136 @@ 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 ComputeRoute(PhantomNodes & phantomNodes, vector<_PathData> & path) {
unsigned int _upperbound = UINT_MAX;
if(!phantomNodes.AtLeastOnePhantomNodeIsUINTMAX())
return _upperbound;
EdgeID sourceEdgeID = _graph->FindEdgeIndicateIfReverse( phantomNodes.startPhantom.startNode, phantomNodes.startPhantom.targetNode, startEdgeIsReversedInGraph);
if(sourceEdgeID == UINT_MAX){
return _upperbound;
}
EdgeID targetEdgeID = _graph->FindEdgeIndicateIfReverse( phantomNodes.targetPhantom.startNode, phantomNodes.targetPhantom.targetNode, targetEdgeIsReversed);
if(targetEdgeID == UINT_MAX){
return _upperbound;
}
_InsertedNodes _insertedNodes;
_Heap _forwardHeap(nodeHelpDesk->getNumberOfNodes());
_Heap _backwardHeap(nodeHelpDesk->getNumberOfNodes());
InitializeThreadLocalStorageIfNecessary();
NodeID middle = ( NodeID ) UINT_MAX;
if( phantomNodes.PhantomsAreOnSameEdge() ) {
const EdgeData& currentEdgeData = _graph->GetEdgeData(sourceEdgeID);
EdgeWeight w = currentEdgeData.distance;
//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;
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
const EdgeData& sourceEdgeData = _graph->GetEdgeData(sourceEdgeID);
EdgeWeight sw = sourceEdgeData.distance;
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);
_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);
}
//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);
_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 );
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(_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 ( false == _insertedNodes.isForwardInserted(pathNode) ) {
pathNode = _forwardHeap.GetData( pathNode ).parent;
packedPath.push_front( pathNode );
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);
}
packedPath.push_back( middle );
// INFO("Finished getting packed forward path: " << packedPath.size());
packedPath.push_back(middle);
pathNode = middle;
while ( false == _insertedNodes.isBackwardInserted(pathNode) ){
pathNode = _backwardHeap.GetData( pathNode ).parent;
packedPath.push_back( pathNode );
while(phantomNodes.targetPhantom.edgeBasedNode != pathNode && (!phantomNodes.targetPhantom.isBidirected || phantomNodes.targetPhantom.edgeBasedNode+1 != 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);
// 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);
}
packedPath.clear();
return _upperbound/10;
return _upperbound;
}
unsigned int ComputeDistanceBetweenNodes(NodeID start, NodeID target) {
_Heap _forwardHeap(_graph->GetNumberOfNodes());
_Heap _backwardHeap(_graph->GetNumberOfNodes());
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);
}
}
_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());
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);
_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);
}
}
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 );
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) {
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) {
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)
if(s == t)
return 0;
EdgeID e = _graph->FindEdge( s, t );
EdgeID e = _graph->FindEdge(s, t);
if(e == UINT_MAX)
e = _graph->FindEdge( t, s );
if(UINT_MAX == e) {
@ -289,12 +218,12 @@ public:
}
assert(e != UINT_MAX);
const EdgeData ed = _graph->GetEdgeData(e);
return ed.middleName.nameID;
return ed.via;
}
inline NodeID GetWeightForOriginDestinationNodeID(NodeID s, NodeID t) const {
assert(s!=t);
EdgeID e = _graph->FindEdge( s, t );
EdgeID e = _graph->FindEdge(s, t);
if(e == UINT_MAX)
e = _graph->FindEdge( t, s );
assert(e != UINT_MAX);
@ -302,22 +231,22 @@ public:
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) );
return (GetEscapedNameForNameID(nameID));
}
inline std::string GetEscapedNameForNameID(const NodeID nameID) const {
return ( (nameID >= _names->size() || nameID == 0) ? std::string("") : HTMLEntitize(_names->at(nameID)) );
return ((nameID >= _names->size() || nameID == 0) ? std::string("") : HTMLEntitize(_names->at(nameID)));
}
inline short GetTypeOfEdgeForOriginDestinationNodeID(NodeID s, NodeID t) const {
assert(s!=t);
EdgeID e = _graph->FindEdge( s, t );
EdgeID e = _graph->FindEdge(s, t);
if(e == UINT_MAX)
e = _graph->FindEdge( t, s );
assert(e != UINT_MAX);
@ -325,28 +254,23 @@ public:
return ed.type;
}
// inline void RegisterThread(const unsigned k, const unsigned v) {
// nodeHelpDesk->RegisterThread(k,v);
// }
private:
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 ) {
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;
}
}
if ( distance > *_upperbound ) {
_forwardHeap.DeleteAll();
if(distance > *_upperbound){
_forwardHeap->DeleteAll();
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;
@ -354,56 +278,56 @@ 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++ ) {
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();
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 ) {
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 ) {
if(distance > *_upperbound) {
stats.meetingNodes++;
_forwardHeap.DeleteAll();
_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);
@ -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,14 +348,14 @@ 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
}
@ -439,42 +363,47 @@ private:
}
}
inline bool _UnpackEdge( const NodeID source, const NodeID target, std::vector< _PathData >& path ) {
inline bool _UnpackEdge(const NodeID source, const NodeID target, std::vector<_PathData> & path) {
assert(source != target);
//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++) {
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;
}
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_ */

View File

@ -49,7 +49,7 @@ public:
}
};
StaticGraph( int nodes, std::vector< InputEdge > &graph ) {
StaticGraph( const int nodes, std::vector< InputEdge > &graph ) {
#ifdef _GLIBCXX_PARALLEL
__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
}

View File

@ -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 + "\" ";

View File

@ -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;
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);
}
}
for(vector< _PathData >::const_iterator it = path.begin(); it != path.end(); it++) {
sEngine.getCoordinatesForNodeID(it->node, descriptorState.nextCoordinate);
descriptorState.currentNameID = sEngine.GetNameIDForOriginDestinationNodeID(lastNodeID, it->node);
double area = fabs(0.5*( descriptorState.startOfSegmentCoordinate.lon*(descriptorState.nextCoordinate.lat - descriptorState.currentCoordinate.lat) + descriptorState.nextCoordinate.lon*(descriptorState.currentCoordinate.lat - descriptorState.startOfSegmentCoordinate.lat) + descriptorState.currentCoordinate.lon*(descriptorState.startOfSegmentCoordinate.lat - descriptorState.nextCoordinate.lat) ) );
//if route is generalization does not skip this point, add it to description
if( config.z == 19 || area >= areaThresholds[config.z] || (false == descriptorState.CurrentAndPreviousNameIDsEqual()) ) {
//mark the beginning of the segment thats announced
// appendCoordinateToString(descriptorState.currentCoordinate, descriptorState.routeGeometryString);
polyline.push_back(descriptorState.currentCoordinate);
descriptorState.geometryCounter++;
if( ( false == descriptorState.CurrentAndPreviousNameIDsEqual() ) && config.instructions) {
appendInstructionLengthToString(descriptorState.distanceOfInstruction, descriptorState.routeInstructionString);
descriptorState.routeInstructionString += ",";
getTurnDirectionOfInstruction(descriptorState.GetAngleBetweenCoordinates(), tmp);
appendInstructionNameToString(sEngine.GetEscapedNameForNameID(descriptorState.currentNameID), tmp, descriptorState.routeInstructionString);
//note the new segment starting coordinates
descriptorState.SetStartOfSegment();
}
}
descriptorState.distanceOfInstruction += ApproximateDistance(descriptorState.currentCoordinate, descriptorState.nextCoordinate);
lastNodeID = it->node;
if(it != path.begin()) {
descriptorState.previousCoordinate = descriptorState.currentCoordinate;
descriptorState.currentCoordinate = descriptorState.nextCoordinate;
}
}
}
descriptorState.currentNameID = sEngine.GetNameIDForOriginDestinationNodeID(phantomNodes.targetPhantom.startNode, phantomNodes.targetPhantom.targetNode);
descriptorState.nextCoordinate = phantomNodes.targetPhantom.location;
polyline.push_back(descriptorState.currentCoordinate);
descriptorState.geometryCounter++;
if((false == descriptorState.CurrentAndPreviousNameIDsEqual()) && config.instructions) {
appendInstructionLengthToString(descriptorState.distanceOfInstruction, descriptorState.routeInstructionString);
descriptorState.routeInstructionString += ",";
getTurnDirectionOfInstruction(descriptorState.GetAngleBetweenCoordinates(), tmp);
appendInstructionNameToString(sEngine.GetEscapedNameForNameID(descriptorState.currentNameID), tmp, descriptorState.routeInstructionString);
descriptorState.distanceOfInstruction = 0;
descriptorState.SetStartOfSegment();
}
summary.destName = sEngine.GetEscapedNameForNameID(descriptorState.currentNameID);
descriptorState.distanceOfInstruction += ApproximateDistance(descriptorState.currentCoordinate, descriptorState.nextCoordinate);
polyline.push_back(phantomNodes.targetPhantom.location);
descriptorState.geometryCounter++;
appendInstructionLengthToString(descriptorState.distanceOfInstruction, descriptorState.routeInstructionString);
summary.BuildDurationAndLengthStrings(descriptorState.entireDistance, distance);
} else {
//no route found
reply.content += "207,"

View File

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

View File

@ -28,28 +28,30 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "../DataStructures/StaticGraph.h"
#include "../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);

View File

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

View File

@ -33,7 +33,6 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "BasePlugin.h"
#include "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;
}

View File

@ -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)
@ -362,96 +362,41 @@ NodeID readDDSGGraphFromStream(istream &in, vector<EdgeT>& edgeList, vector<Node
}
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)
numberOfNodes = target;
if(middle > numberOfNodes)
numberOfNodes = middle;
edgeList.push_back(g);
INFO("looked at source " << source);
}
if(target > numberOfNodes) {
numberOfNodes = target;
}
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

View File

@ -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;

View File

@ -42,7 +42,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
int omp_get_num_procs() { return 1; }
int omp_get_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,11 +67,10 @@ 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;
@ -83,7 +82,6 @@ int main (int argc, char *argv[]) {
}
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;
}

View File

@ -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");

View File

@ -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));