Support for multi-segment routes. Needs to be further tested

This commit is contained in:
Dennis Luxen
2011-07-07 16:51:23 +00:00
parent ccf40b53eb
commit c60c3fcd3c
7 changed files with 681 additions and 712 deletions
-15
View File
@@ -346,21 +346,6 @@ inline double ApproximateDistance( const int lat1, const int lon1, const int lat
return EARTH_RADIUS_IN_METERS * distanceArc;
}
/* Get angle of line segment (A,C)->(C,B), atan2 magic, formerly cosine theorem*/
double GetAngleBetweenTwoEdges(const _Coordinate& A, const _Coordinate& C, const _Coordinate& B) {
int v1x = A.lon - C.lon;
int v1y = A.lat - C.lat;
int v2x = B.lon - C.lon;
int v2y = B.lat - C.lat;
double angle = (atan2(v2y,v2x) - atan2(v1y,v1x) )*180/M_PI;
while(angle < 0)
angle += 360;
return angle;
}
inline double ApproximateDistance(const _Coordinate &c1, const _Coordinate &c2) {
return ApproximateDistance( c1.lat, c1.lon, c2.lat, c2.lon );
}
+67 -42
View File
@@ -85,7 +85,7 @@ struct _InsertedNodes {
};
typedef BinaryHeap< NodeID, int, int, _HeapData, DenseStorage< NodeID, unsigned > > _Heap;
typedef BinaryHeap< NodeID, int, int, _HeapData/*, ArrayS< NodeID, unsigned >*/ > _Heap;
template<typename EdgeData, typename GraphT, typename NodeHelperT = NodeInformationHelpDesk>
class SearchEngine {
@@ -98,8 +98,7 @@ public:
SearchEngine(GraphT * g, NodeHelperT * nh, vector<string> * n = new vector<string>()) : _graph(g), nodeHelpDesk(nh), _names(n) {}
~SearchEngine() {}
inline const void getNodeInfo(NodeID id, _Coordinate& result) const
{
inline const void getCoordinatesForNodeID(NodeID id, _Coordinate& result) const {
result.lat = nodeHelpDesk->getLatitudeOfNode(id);
result.lon = nodeHelpDesk->getLongitudeOfNode(id);
}
@@ -108,7 +107,7 @@ public:
return nodeHelpDesk->getNumberOfNodes();
}
unsigned int ComputeRoute(PhantomNodes * phantomNodes, vector<_PathData > * path, _Coordinate& startCoord, _Coordinate& targetCoord) {
unsigned int ComputeRoute(PhantomNodes * phantomNodes, vector<_PathData > * path) {
bool onSameEdge = false;
bool onSameEdgeReversed = false;
@@ -122,7 +121,7 @@ public:
NodeID middle = ( NodeID ) 0;
unsigned int _upperbound = std::numeric_limits<unsigned int>::max();
if(phantomNodes->startNode1 == UINT_MAX || phantomNodes->startNode2 == UINT_MAX)
if(phantomNodes->startNode1 == UINT_MAX || phantomNodes->targetNode1 == UINT_MAX || phantomNodes->startNode2 == UINT_MAX || phantomNodes->targetNode2 == UINT_MAX)
return _upperbound;
if( (phantomNodes->startNode1 == phantomNodes->targetNode1 && phantomNodes->startNode2 == phantomNodes->targetNode2 ) ||
@@ -210,12 +209,13 @@ public:
while(_forwardHeap.Size() + _backwardHeap.Size() > 0) {
if ( _forwardHeap.Size() > 0 ) {
_RoutingStep( &_forwardHeap, &_backwardHeap, true, &middle, &_upperbound );
_RoutingStep( _forwardHeap, _backwardHeap, true, &middle, &_upperbound );
}
if ( _backwardHeap.Size() > 0 ) {
_RoutingStep( &_backwardHeap, &_forwardHeap, false, &middle, &_upperbound );
_RoutingStep( _backwardHeap, _forwardHeap, false, &middle, &_upperbound );
}
}
// std::cout << "[debug] computing distance took " << get_timestamp() - time << std::endl;
// time = get_timestamp();
@@ -245,7 +245,6 @@ public:
}
packedPath.clear();
// std::cout << "[debug] unpacking path took " << get_timestamp() - time << std::endl;
return _upperbound/10;
}
@@ -304,8 +303,7 @@ public:
}
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;
}
@@ -334,6 +332,12 @@ public:
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 GetEscapedNameForNameID(const NodeID nameID) const {
return ( (nameID >= _names->size() || nameID == 0) ? std::string("") : HTMLEntitize(_names->at(nameID)) );
}
@@ -353,63 +357,84 @@ public:
}
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;
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();
_forwardHeap.DeleteAll();
return;
}
for ( typename GraphT::EdgeIterator edge = _graph->BeginEdges( node ); edge < _graph->EndEdges(node); edge++ ) {
const EdgeData& ed = _graph->GetEdgeData(edge);
//const EdgeData& ed = _graph->GetEdgeData(edge);
// if(!ed.shortcut)
// continue;
const NodeID to = _graph->GetTarget(edge);
const EdgeWeight edgeWeight = ed.distance;
const EdgeWeight edgeWeight = _graph->GetEdgeData(edge).distance;
assert( edgeWeight > 0 );
const int toDistance = distance + edgeWeight;
//const int toDistance = distance + edgeWeight;
//Stalling
if(_forwardHeap->WasInserted( to )) {
if(!forwardDirection ? ed.forward : ed.backward) {
if(_forwardHeap->GetKey( to ) + edgeWeight < distance) {
// std::cout << "[stalled] node " << node << std::endl;
bool backwardDirectionFlag = (!forwardDirection) ? _graph->GetEdgeData(edge).forward : _graph->GetEdgeData(edge).backward;
if(_forwardHeap.WasInserted( to )) {
if(backwardDirectionFlag) {
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;
if(forwardDirection ? ed.forward : ed.backward ) {
assert( edgeWeight > 0 );
const int toDistance = distance + edgeWeight;
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
}
}
// if(forwardDirection ? ed.forward : ed.backward ) {
// //New Node discovered -> Add to Heap + Node Info Storage
// 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 );
// //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( _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;
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;
@@ -417,7 +442,7 @@ private:
}
if ( distance > *_upperbound ) {
stats.meetingNodes++;
_forwardHeap->DeleteAll();
_forwardHeap.DeleteAll();
return;
}
@@ -431,9 +456,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;
}
@@ -442,14 +467,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
}