Support for 'only_*'-typed turn restrictions.
This commit is contained in:
parent
f601664620
commit
7be723782a
@ -144,7 +144,7 @@ private:
|
|||||||
try {
|
try {
|
||||||
_firstEdge.resize( _numNodes + 1 );
|
_firstEdge.resize( _numNodes + 1 );
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
cerr << "Not enough RAM on machine" << endl;
|
ERR("Not enough RAM on machine");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_firstEdge[0] = 0;
|
_firstEdge[0] = 0;
|
||||||
@ -164,7 +164,7 @@ private:
|
|||||||
threadData.push_back( new _ThreadData( _numNodes ) );
|
threadData.push_back( new _ThreadData( _numNodes ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << "Scanning for useless shortcuts" << endl;
|
INFO("Scanning for useless shortcuts");
|
||||||
BuildOutgoingGraph();
|
BuildOutgoingGraph();
|
||||||
#pragma omp parallel for
|
#pragma omp parallel for
|
||||||
for ( int i = 0; i < ( int ) _graph.size(); i++ ) {
|
for ( int i = 0; i < ( int ) _graph.size(); i++ ) {
|
||||||
@ -202,7 +202,7 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << "Removing edges" << endl;
|
INFO("Removing edges");
|
||||||
int useful = 0;
|
int useful = 0;
|
||||||
for ( int i = 0; i < ( int ) _graph.size(); i++ ) {
|
for ( int i = 0; i < ( int ) _graph.size(); i++ ) {
|
||||||
if ( !_graph[i].data.forward && !_graph[i].data.backward && _graph[i].data.shortcut )
|
if ( !_graph[i].data.forward && !_graph[i].data.backward && _graph[i].data.shortcut )
|
||||||
@ -210,7 +210,7 @@ private:
|
|||||||
_graph[useful] = _graph[i];
|
_graph[useful] = _graph[i];
|
||||||
useful++;
|
useful++;
|
||||||
}
|
}
|
||||||
cout << "Removed " << _graph.size() - useful << " useless shortcuts" << endl;
|
INFO("Removed " << _graph.size() - useful << " useless shortcuts");
|
||||||
_graph.resize( useful );
|
_graph.resize( useful );
|
||||||
|
|
||||||
for ( int threadNum = 0; threadNum < maxThreads; ++threadNum ) {
|
for ( int threadNum = 0; threadNum < maxThreads; ++threadNum ) {
|
||||||
@ -223,6 +223,11 @@ private:
|
|||||||
const NodeID node = heapForward->DeleteMin();
|
const NodeID node = heapForward->DeleteMin();
|
||||||
const int distance = heapForward->GetKey( node );
|
const int distance = heapForward->GetKey( node );
|
||||||
|
|
||||||
|
if ( distance > *targetDistance ) {
|
||||||
|
heapForward->DeleteAll();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ( heapBackward->WasInserted( node ) ) {
|
if ( heapBackward->WasInserted( node ) ) {
|
||||||
const int newDistance = heapBackward->GetKey( node ) + distance;
|
const int newDistance = heapBackward->GetKey( node ) + distance;
|
||||||
if ( newDistance < *targetDistance ) {
|
if ( newDistance < *targetDistance ) {
|
||||||
@ -231,11 +236,7 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( distance > *targetDistance ) {
|
for ( int edge = _firstEdge[node], endEdges = _firstEdge[node + 1]; edge != endEdges; ++edge ) {
|
||||||
heapForward->DeleteAll();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for ( int edge = _firstEdge[node], endEdges = _firstEdge[node + 1]; edge != endEdges; ++edge ) {
|
|
||||||
const NodeID to = _graph[edge].target;
|
const NodeID to = _graph[edge].target;
|
||||||
const int edgeWeight = _graph[edge].data.distance;
|
const int edgeWeight = _graph[edge].data.distance;
|
||||||
assert( edgeWeight > 0 );
|
assert( edgeWeight > 0 );
|
||||||
@ -256,15 +257,15 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int _ComputeDistance( NodeID source, NodeID target, _ThreadData * data, std::vector< NodeID >* path = NULL ) {
|
int _ComputeDistance( NodeID source, NodeID target, _ThreadData * data ) {
|
||||||
data->_heapForward->Clear();
|
data->_heapForward->Clear();
|
||||||
data->_heapBackward->Clear();
|
data->_heapBackward->Clear();
|
||||||
//insert source into heap
|
//insert source into heap
|
||||||
data->_heapForward->Insert( source, 0, source );
|
data->_heapForward->Insert( source, 0, source );
|
||||||
data->_heapBackward->Insert( target, 0, target );
|
data->_heapBackward->Insert( target, 0, target );
|
||||||
|
|
||||||
int targetDistance = (std::numeric_limits< int >::max)();
|
int targetDistance = std::numeric_limits< int >::max();
|
||||||
NodeID middle = (std::numeric_limits<NodeID>::max)();
|
NodeID middle = std::numeric_limits<NodeID>::max();
|
||||||
|
|
||||||
while ( data->_heapForward->Size() + data->_heapBackward->Size() > 0 ) {
|
while ( data->_heapForward->Size() + data->_heapBackward->Size() > 0 ) {
|
||||||
if ( data->_heapForward->Size() > 0 ) {
|
if ( data->_heapForward->Size() > 0 ) {
|
||||||
|
@ -99,6 +99,7 @@ void EdgeBasedGraphFactory::Run() {
|
|||||||
Percent p(_nodeBasedGraph->GetNumberOfNodes());
|
Percent p(_nodeBasedGraph->GetNumberOfNodes());
|
||||||
int numberOfResolvedRestrictions(0);
|
int numberOfResolvedRestrictions(0);
|
||||||
int nodeBasedEdgeCounter(0);
|
int nodeBasedEdgeCounter(0);
|
||||||
|
NodeID onlyToNode(0);
|
||||||
|
|
||||||
//Loop over all nodes u. Three nested loop look super-linear, but we are dealing with a number linear in the turns only.
|
//Loop over all nodes u. Three nested loop look super-linear, but we are dealing with a number linear in the turns only.
|
||||||
for(_NodeBasedDynamicGraph::NodeIterator u = 0; u < _nodeBasedGraph->GetNumberOfNodes(); ++u ) {
|
for(_NodeBasedDynamicGraph::NodeIterator u = 0; u < _nodeBasedGraph->GetNumberOfNodes(); ++u ) {
|
||||||
@ -110,29 +111,56 @@ void EdgeBasedGraphFactory::Run() {
|
|||||||
++nodeBasedEdgeCounter;
|
++nodeBasedEdgeCounter;
|
||||||
_NodeBasedDynamicGraph::NodeIterator v = _nodeBasedGraph->GetTarget(e1);
|
_NodeBasedDynamicGraph::NodeIterator v = _nodeBasedGraph->GetTarget(e1);
|
||||||
//loop over all reachable edges (v,w)
|
//loop over all reachable edges (v,w)
|
||||||
|
bool isOnlyAllowed(false);
|
||||||
|
|
||||||
|
//Check every turn restriction originating from this edge if it is an 'only_*'-turn.
|
||||||
|
if(restrictionIterator != inputRestrictions.end() && u == restrictionIterator->fromNode) {
|
||||||
|
std::vector<_Restriction>::iterator secondRestrictionIterator = restrictionIterator;
|
||||||
|
do {
|
||||||
|
if(v == secondRestrictionIterator->viaNode) {
|
||||||
|
if(secondRestrictionIterator->flags.isOnly) {
|
||||||
|
isOnlyAllowed = true;
|
||||||
|
onlyToNode = secondRestrictionIterator->toNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++secondRestrictionIterator;
|
||||||
|
} while(u == secondRestrictionIterator->fromNode);
|
||||||
|
}
|
||||||
|
|
||||||
for(_NodeBasedDynamicGraph::EdgeIterator e2 = _nodeBasedGraph->BeginEdges(v); e2 < _nodeBasedGraph->EndEdges(v); ++e2) {
|
for(_NodeBasedDynamicGraph::EdgeIterator e2 = _nodeBasedGraph->BeginEdges(v); e2 < _nodeBasedGraph->EndEdges(v); ++e2) {
|
||||||
_NodeBasedDynamicGraph::NodeIterator w = _nodeBasedGraph->GetTarget(e2);
|
_NodeBasedDynamicGraph::NodeIterator w = _nodeBasedGraph->GetTarget(e2);
|
||||||
//if (u,v,w) is a forbidden turn, continue
|
//if (u,v,w) is a forbidden turn, continue
|
||||||
bool isTurnProhibited = false;
|
bool isTurnRestricted(false);
|
||||||
|
if(isOnlyAllowed && w != onlyToNode) {
|
||||||
|
// INFO("skipped turn <" << u << "," << v << "," << w << ">, only allowing <" << u << "," << v << "," << onlyToNode << ">");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if( u != w ) { //only add an edge if turn is not a U-turn
|
if( u != w ) { //only add an edge if turn is not a U-turn
|
||||||
if(restrictionIterator != inputRestrictions.end() && u == restrictionIterator->fromNode) {
|
if(restrictionIterator != inputRestrictions.end() && u == restrictionIterator->fromNode) {
|
||||||
std::vector<_Restriction>::iterator secondRestrictionIterator = restrictionIterator;
|
std::vector<_Restriction>::iterator secondRestrictionIterator = restrictionIterator;
|
||||||
do {
|
do {
|
||||||
if( v == secondRestrictionIterator->viaNode && w == secondRestrictionIterator->toNode) {
|
if(v == secondRestrictionIterator->viaNode) {
|
||||||
isTurnProhibited = true;
|
if(w == secondRestrictionIterator->toNode) {
|
||||||
|
isTurnRestricted = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
++secondRestrictionIterator;
|
++secondRestrictionIterator;
|
||||||
} while(u == secondRestrictionIterator->fromNode);
|
} while(u == secondRestrictionIterator->fromNode);
|
||||||
}
|
}
|
||||||
if( !isTurnProhibited ) { //only add an edge if turn is not prohibited
|
|
||||||
|
if( !isTurnRestricted || (isOnlyAllowed && w == onlyToNode) ) { //only add an edge if turn is not prohibited
|
||||||
|
if(isOnlyAllowed && w == onlyToNode) {
|
||||||
|
// INFO("Adding 'only_*'-turn <" << u << "," << v << "," << w << ">");
|
||||||
|
} else if(isOnlyAllowed && w != onlyToNode) {
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
//new costs for edge based edge (e1, e2) = cost (e1) + tc(e1,e2)
|
//new costs for edge based edge (e1, e2) = cost (e1) + tc(e1,e2)
|
||||||
const _NodeBasedDynamicGraph::NodeIterator edgeBasedSource = _nodeBasedGraph->GetEdgeData(e1).edgeBasedNodeID;
|
const _NodeBasedDynamicGraph::NodeIterator edgeBasedSource = _nodeBasedGraph->GetEdgeData(e1).edgeBasedNodeID;
|
||||||
// INFO("edgeBasedSource: " << edgeBasedSource);
|
|
||||||
if(edgeBasedSource > _nodeBasedGraph->GetNumberOfEdges()) {
|
if(edgeBasedSource > _nodeBasedGraph->GetNumberOfEdges()) {
|
||||||
ERR("edgeBasedTarget" << edgeBasedSource << ">" << _nodeBasedGraph->GetNumberOfEdges());
|
ERR("edgeBasedTarget" << edgeBasedSource << ">" << _nodeBasedGraph->GetNumberOfEdges());
|
||||||
}
|
}
|
||||||
const _NodeBasedDynamicGraph::NodeIterator edgeBasedTarget = _nodeBasedGraph->GetEdgeData(e2).edgeBasedNodeID;
|
const _NodeBasedDynamicGraph::NodeIterator edgeBasedTarget = _nodeBasedGraph->GetEdgeData(e2).edgeBasedNodeID;
|
||||||
// INFO("edgeBasedTarget: " << edgeBasedTarget);
|
|
||||||
if(edgeBasedTarget > _nodeBasedGraph->GetNumberOfEdges()) {
|
if(edgeBasedTarget > _nodeBasedGraph->GetNumberOfEdges()) {
|
||||||
ERR("edgeBasedTarget" << edgeBasedTarget << ">" << _nodeBasedGraph->GetNumberOfEdges());
|
ERR("edgeBasedTarget" << edgeBasedTarget << ">" << _nodeBasedGraph->GetNumberOfEdges());
|
||||||
}
|
}
|
||||||
@ -145,7 +173,6 @@ void EdgeBasedGraphFactory::Run() {
|
|||||||
short turnInstruction = AnalyzeTurn(u, v, w);
|
short turnInstruction = AnalyzeTurn(u, v, w);
|
||||||
|
|
||||||
//create edge-based graph edge
|
//create edge-based graph edge
|
||||||
//EdgeBasedEdge(NodeID s, NodeID t, NodeID v, unsigned n1, EdgeWeight w, bool f, bool b, short ty)
|
|
||||||
EdgeBasedEdge newEdge(edgeBasedSource, edgeBasedTarget, v, nameID, distance, true, false, turnInstruction);
|
EdgeBasedEdge newEdge(edgeBasedSource, edgeBasedTarget, v, nameID, distance, true, false, turnInstruction);
|
||||||
edgeBasedEdges.push_back(newEdge);
|
edgeBasedEdges.push_back(newEdge);
|
||||||
EdgeBasedNode currentNode;
|
EdgeBasedNode currentNode;
|
||||||
|
@ -121,7 +121,7 @@ public:
|
|||||||
//Is the highway tag listed as usable way?
|
//Is the highway tag listed as usable way?
|
||||||
if(0 < settings[highway]) {
|
if(0 < settings[highway]) {
|
||||||
|
|
||||||
if(0 != maxspeed)
|
if(0 < maxspeed)
|
||||||
w.speed = maxspeed;
|
w.speed = maxspeed;
|
||||||
else
|
else
|
||||||
w.speed = settings[highway];
|
w.speed = settings[highway];
|
||||||
@ -154,7 +154,6 @@ public:
|
|||||||
//Is the route tag listed as usable way in the profile?
|
//Is the route tag listed as usable way in the profile?
|
||||||
if(settings[route] > 0 || settings[man_made] > 0) {
|
if(settings[route] > 0 || settings[man_made] > 0) {
|
||||||
w.useful = true;
|
w.useful = true;
|
||||||
w.direction = _Way::oneway;
|
|
||||||
w.speed = settings[route];
|
w.speed = settings[route];
|
||||||
w.direction = _Way::bidirectional;
|
w.direction = _Way::bidirectional;
|
||||||
}
|
}
|
||||||
@ -178,7 +177,7 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if(w.id == UINT_MAX) {
|
if(w.id == UINT_MAX) {
|
||||||
WARN("found way with unknown type" << w.id);
|
WARN("found way with unknown type: " << w.id);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,10 +177,10 @@ struct _RawRestrictionContainer {
|
|||||||
_Restriction restriction;
|
_Restriction restriction;
|
||||||
EdgeID fromWay;
|
EdgeID fromWay;
|
||||||
EdgeID toWay;
|
EdgeID toWay;
|
||||||
unsigned viaWay;
|
unsigned viaNode;
|
||||||
|
|
||||||
_RawRestrictionContainer(EdgeID f, EdgeID t, NodeID vn, unsigned vw) : fromWay(f), toWay(t), viaWay(vw) { restriction.viaNode = vn;}
|
_RawRestrictionContainer(EdgeID f, EdgeID t, NodeID vn, unsigned vw) : fromWay(f), toWay(t), viaNode(vw) { restriction.viaNode = vn;}
|
||||||
_RawRestrictionContainer(bool isOnly = false) : fromWay(UINT_MAX), toWay(UINT_MAX), viaWay(UINT_MAX) { restriction.flags.isOnly = isOnly;}
|
_RawRestrictionContainer(bool isOnly = false) : fromWay(UINT_MAX), toWay(UINT_MAX), viaNode(UINT_MAX) { restriction.flags.isOnly = isOnly;}
|
||||||
|
|
||||||
static _RawRestrictionContainer min_value() {
|
static _RawRestrictionContainer min_value() {
|
||||||
return _RawRestrictionContainer((numeric_limits<unsigned>::min)(), (numeric_limits<unsigned>::min)(), (numeric_limits<unsigned>::min)(), (numeric_limits<unsigned>::min)());
|
return _RawRestrictionContainer((numeric_limits<unsigned>::min)(), (numeric_limits<unsigned>::min)(), (numeric_limits<unsigned>::min)(), (numeric_limits<unsigned>::min)());
|
||||||
@ -233,7 +233,7 @@ struct _WayIDStartAndEndEdge {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CmpWayStartAndEnd : public std::binary_function<_WayIDStartAndEndEdge, _WayIDStartAndEndEdge, bool> {
|
struct CmpWayByID : public std::binary_function<_WayIDStartAndEndEdge, _WayIDStartAndEndEdge, bool> {
|
||||||
typedef _WayIDStartAndEndEdge value_type;
|
typedef _WayIDStartAndEndEdge value_type;
|
||||||
bool operator () (const _WayIDStartAndEndEdge & a, const _WayIDStartAndEndEdge & b) const {
|
bool operator () (const _WayIDStartAndEndEdge & a, const _WayIDStartAndEndEdge & b) const {
|
||||||
return a.wayID < b.wayID;
|
return a.wayID < b.wayID;
|
||||||
|
@ -270,9 +270,9 @@ private:
|
|||||||
if("from" == role || "to" == role) //Only via should be a node
|
if("from" == role || "to" == role) //Only via should be a node
|
||||||
continue;
|
continue;
|
||||||
assert("via" == role);
|
assert("via" == role);
|
||||||
if(UINT_MAX != currentRestrictionContainer.viaWay)
|
if(UINT_MAX != currentRestrictionContainer.viaNode)
|
||||||
currentRestrictionContainer.viaWay = UINT_MAX;
|
currentRestrictionContainer.viaNode = UINT_MAX;
|
||||||
assert(UINT_MAX == currentRestrictionContainer.viaWay);
|
assert(UINT_MAX == currentRestrictionContainer.viaNode);
|
||||||
currentRestrictionContainer.restriction.viaNode = lastRef;
|
currentRestrictionContainer.restriction.viaNode = lastRef;
|
||||||
break;
|
break;
|
||||||
case 1: //way
|
case 1: //way
|
||||||
@ -285,7 +285,7 @@ private:
|
|||||||
}
|
}
|
||||||
if ("via" == role) {
|
if ("via" == role) {
|
||||||
assert(currentRestrictionContainer.restriction.toNode == UINT_MAX);
|
assert(currentRestrictionContainer.restriction.toNode == UINT_MAX);
|
||||||
currentRestrictionContainer.viaWay = lastRef;
|
currentRestrictionContainer.viaNode = lastRef;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2: //relation, not used. relations relating to relations are evil.
|
case 2: //relation, not used. relations relating to relations are evil.
|
||||||
@ -315,7 +315,6 @@ private:
|
|||||||
for(int i = 0; i < threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).ways_size(); i++) {
|
for(int i = 0; i < threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).ways_size(); i++) {
|
||||||
const OSMPBF::Way& inputWay = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).ways( i );
|
const OSMPBF::Way& inputWay = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).ways( i );
|
||||||
_Way w;
|
_Way w;
|
||||||
w.id = inputWay.id();
|
|
||||||
unsigned pathNode(0);
|
unsigned pathNode(0);
|
||||||
for(int i = 0; i < inputWay.refs_size(); i++) {
|
for(int i = 0; i < inputWay.refs_size(); i++) {
|
||||||
pathNode += inputWay.refs(i);
|
pathNode += inputWay.refs(i);
|
||||||
|
@ -208,7 +208,7 @@ int main (int argc, char *argv[]) {
|
|||||||
time = get_timestamp();
|
time = get_timestamp();
|
||||||
|
|
||||||
cout << "[extractor] Sorting used ways ... " << flush;
|
cout << "[extractor] Sorting used ways ... " << flush;
|
||||||
stxxl::sort(externalMemory.wayStartEndVector.begin(), externalMemory.wayStartEndVector.end(), CmpWayStartAndEnd(), memory_to_use);
|
stxxl::sort(externalMemory.wayStartEndVector.begin(), externalMemory.wayStartEndVector.end(), CmpWayByID(), memory_to_use);
|
||||||
cout << "ok, after " << get_timestamp() - time << "s" << endl;
|
cout << "ok, after " << get_timestamp() - time << "s" << endl;
|
||||||
|
|
||||||
cout << "[extractor] Sorting restrctns. by from... " << flush;
|
cout << "[extractor] Sorting restrctns. by from... " << flush;
|
||||||
@ -255,8 +255,7 @@ int main (int argc, char *argv[]) {
|
|||||||
cout << "[extractor] Fixing restriction ends ... " << flush;
|
cout << "[extractor] Fixing restriction ends ... " << flush;
|
||||||
restrictionsIT = externalMemory.restrictionsVector.begin();
|
restrictionsIT = externalMemory.restrictionsVector.begin();
|
||||||
wayStartAndEndEdgeIT = externalMemory.wayStartEndVector.begin();
|
wayStartAndEndEdgeIT = externalMemory.wayStartEndVector.begin();
|
||||||
while(wayStartAndEndEdgeIT != externalMemory.wayStartEndVector.end() &&
|
while(wayStartAndEndEdgeIT != externalMemory.wayStartEndVector.end() && restrictionsIT != externalMemory.restrictionsVector.end()) {
|
||||||
restrictionsIT != externalMemory.restrictionsVector.end()) {
|
|
||||||
if(wayStartAndEndEdgeIT->wayID < restrictionsIT->toWay){
|
if(wayStartAndEndEdgeIT->wayID < restrictionsIT->toWay){
|
||||||
++wayStartAndEndEdgeIT;
|
++wayStartAndEndEdgeIT;
|
||||||
continue;
|
continue;
|
||||||
@ -278,11 +277,13 @@ int main (int argc, char *argv[]) {
|
|||||||
|
|
||||||
if(UINT_MAX != restrictionsIT->restriction.fromNode && UINT_MAX != restrictionsIT->restriction.toNode) {
|
if(UINT_MAX != restrictionsIT->restriction.fromNode && UINT_MAX != restrictionsIT->restriction.toNode) {
|
||||||
++usableRestrictionsCounter;
|
++usableRestrictionsCounter;
|
||||||
|
} else {
|
||||||
|
INFO("Restriction from: " << restrictionsIT->restriction.fromNode << ", to: " << restrictionsIT->restriction.toNode);
|
||||||
}
|
}
|
||||||
++restrictionsIT;
|
++restrictionsIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << "ok, after " << get_timestamp() - time << "s" << endl;
|
cout << "ok, after " << get_timestamp() - time << "s" << endl;
|
||||||
|
INFO("usable restrictions: " << usableRestrictionsCounter);
|
||||||
//serialize restrictions
|
//serialize restrictions
|
||||||
ofstream restrictionsOutstream;
|
ofstream restrictionsOutstream;
|
||||||
restrictionsOutstream.open(restrictionsFileName.c_str(), ios::binary);
|
restrictionsOutstream.open(restrictionsFileName.c_str(), ios::binary);
|
||||||
|
Loading…
Reference in New Issue
Block a user