Merge branch 'develop' into experimental/program_options

This commit is contained in:
Dennis Luxen 2013-08-19 17:03:47 +02:00
commit 9d23dee3fc
33 changed files with 1021 additions and 710 deletions

View File

@ -35,11 +35,13 @@ Strongly connected components using Tarjan's Algorithm
#include "../Util/SimpleLogger.h" #include "../Util/SimpleLogger.h"
#include <boost/assert.hpp>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/integer.hpp> #include <boost/integer.hpp>
#include <boost/make_shared.hpp> #include <boost/make_shared.hpp>
#include <boost/unordered_map.hpp> #include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp>
#ifdef __APPLE__ #ifdef __APPLE__
#include <gdal.h> #include <gdal.h>
@ -48,7 +50,7 @@ Strongly connected components using Tarjan's Algorithm
#include <gdal/gdal.h> #include <gdal/gdal.h>
#include <gdal/ogrsf_frmts.h> #include <gdal/ogrsf_frmts.h>
#endif #endif
#include <cassert>
#include <stack> #include <stack>
#include <vector> #include <vector>
@ -64,7 +66,6 @@ private:
struct TarjanEdgeData { struct TarjanEdgeData {
int distance; int distance;
unsigned edgeBasedNodeID;
unsigned nameID:31; unsigned nameID:31;
bool shortcut:1; bool shortcut:1;
short type; short type;
@ -77,7 +78,10 @@ private:
}; };
struct TarjanStackFrame { struct TarjanStackFrame {
explicit TarjanStackFrame(NodeID _v, NodeID p) : v(_v), parent(p) {} explicit TarjanStackFrame(
NodeID v,
NodeID parent
) : v(v), parent(parent) { }
NodeID v; NodeID v;
NodeID parent; NodeID parent;
}; };
@ -85,18 +89,17 @@ private:
typedef DynamicGraph<TarjanEdgeData> TarjanDynamicGraph; typedef DynamicGraph<TarjanEdgeData> TarjanDynamicGraph;
typedef TarjanDynamicGraph::InputEdge TarjanEdge; typedef TarjanDynamicGraph::InputEdge TarjanEdge;
typedef std::pair<NodeID, NodeID> RestrictionSource; typedef std::pair<NodeID, NodeID> RestrictionSource;
typedef std::pair<NodeID, bool> RestrictionTarget; typedef std::pair<NodeID, bool> restriction_target;
typedef std::vector<RestrictionTarget> EmanatingRestrictionsVector; typedef std::vector<restriction_target> EmanatingRestrictionsVector;
typedef boost::unordered_map<RestrictionSource, unsigned > RestrictionMap; typedef boost::unordered_map<RestrictionSource, unsigned > RestrictionMap;
std::vector<NodeInfo> inputNodeInfoList; std::vector<NodeInfo> m_coordinate_list;
unsigned numberOfTurnRestrictions; std::vector<EmanatingRestrictionsVector> m_restriction_bucket_list;
boost::shared_ptr<TarjanDynamicGraph> _nodeBasedGraph; boost::shared_ptr<TarjanDynamicGraph> m_node_based_graph;
boost::unordered_map<NodeID, bool> _barrierNodes; boost::unordered_set<NodeID> m_barrier_node_list;
boost::unordered_map<NodeID, bool> _trafficLights; boost::unordered_set<NodeID> m_traffic_light_list;
unsigned m_restriction_counter;
std::vector<EmanatingRestrictionsVector> _restrictionBucketVector; RestrictionMap m_restriction_map;
RestrictionMap _restrictionMap;
struct EdgeBasedNode { struct EdgeBasedNode {
bool operator<(const EdgeBasedNode & other) const { bool operator<(const EdgeBasedNode & other) const {
@ -116,93 +119,99 @@ private:
bool ignoreInGrid:1; bool ignoreInGrid:1;
}; };
DeallocatingVector<EdgeBasedNode> edgeBasedNodes;
public: public:
TarjanSCC( TarjanSCC(
int nodes, int number_of_nodes,
std::vector<NodeBasedEdge> & inputEdges, std::vector<NodeBasedEdge> & input_edges,
std::vector<NodeID> & bn, std::vector<NodeID> & bn,
std::vector<NodeID> & tl, std::vector<NodeID> & tl,
std::vector<TurnRestriction> & irs, std::vector<TurnRestriction> & irs,
std::vector<NodeInfo> & nI std::vector<NodeInfo> & nI
) : ) :
inputNodeInfoList(nI), m_coordinate_list(nI),
numberOfTurnRestrictions(irs.size()) m_restriction_counter(irs.size())
{ {
BOOST_FOREACH(const TurnRestriction & restriction, irs) { BOOST_FOREACH(const TurnRestriction & restriction, irs) {
std::pair<NodeID, NodeID> restrictionSource = std::make_pair( std::pair<NodeID, NodeID> restrictionSource = std::make_pair(
restriction.fromNode, restriction.viaNode restriction.fromNode, restriction.viaNode
); );
unsigned index; unsigned index;
RestrictionMap::iterator restrIter = _restrictionMap.find(restrictionSource); RestrictionMap::iterator restriction_iterator = m_restriction_map.find(restrictionSource);
if(restrIter == _restrictionMap.end()) { if(restriction_iterator == m_restriction_map.end()) {
index = _restrictionBucketVector.size(); index = m_restriction_bucket_list.size();
_restrictionBucketVector.resize(index+1); m_restriction_bucket_list.resize(index+1);
_restrictionMap[restrictionSource] = index; m_restriction_map[restrictionSource] = index;
} else { } else {
index = restrIter->second; index = restriction_iterator->second;
//Map already contains an is_only_*-restriction //Map already contains an is_only_*-restriction
if(_restrictionBucketVector.at(index).begin()->second) if(m_restriction_bucket_list.at(index).begin()->second) {
continue; continue;
else if(restriction.flags.isOnly){ } else if(restriction.flags.isOnly) {
//We are going to insert an is_only_*-restriction. There can be only one. //We are going to insert an is_only_*-restriction. There can be only one.
_restrictionBucketVector.at(index).clear(); m_restriction_bucket_list.at(index).clear();
} }
} }
_restrictionBucketVector.at(index).push_back( m_restriction_bucket_list.at(index).push_back(
std::make_pair(restriction.toNode, restriction.flags.isOnly) std::make_pair(restriction.toNode, restriction.flags.isOnly)
); );
} }
BOOST_FOREACH(NodeID id, bn) { m_barrier_node_list.insert(bn.begin(), bn.end());
_barrierNodes[id] = true; m_traffic_light_list.insert(tl.begin(), tl.end());
}
BOOST_FOREACH(NodeID id, tl) {
_trafficLights[id] = true;
}
DeallocatingVector< TarjanEdge > edges;
for ( std::vector< NodeBasedEdge >::const_iterator i = inputEdges.begin(); i != inputEdges.end(); ++i ) {
DeallocatingVector< TarjanEdge > edge_list;
BOOST_FOREACH(const NodeBasedEdge & input_edge, input_edges) {
TarjanEdge edge; TarjanEdge edge;
if(!i->isForward()) { if(!input_edge.isForward()) {
edge.source = i->target(); edge.source = input_edge.target();
edge.target = i->source(); edge.target = input_edge.source();
edge.data.backward = i->isForward(); edge.data.backward = input_edge.isForward();
edge.data.forward = i->isBackward(); edge.data.forward = input_edge.isBackward();
} else { } else {
edge.source = i->source(); edge.source = input_edge.source();
edge.target = i->target(); edge.target = input_edge.target();
edge.data.forward = i->isForward(); edge.data.forward = input_edge.isForward();
edge.data.backward = i->isBackward(); edge.data.backward = input_edge.isBackward();
} }
if(edge.source == edge.target) if(edge.source == edge.target) {
continue; continue;
}
edge.data.distance = (std::max)((int)i->weight(), 1 ); edge.data.distance = (std::max)((int)input_edge.weight(), 1 );
assert( edge.data.distance > 0 ); BOOST_ASSERT( edge.data.distance > 0 );
edge.data.shortcut = false; edge.data.shortcut = false;
edge.data.roundabout = i->isRoundabout(); edge.data.roundabout = input_edge.isRoundabout();
edge.data.ignoreInGrid = i->ignoreInGrid(); edge.data.ignoreInGrid = input_edge.ignoreInGrid();
edge.data.nameID = i->name(); edge.data.nameID = input_edge.name();
edge.data.type = i->type(); edge.data.type = input_edge.type();
edge.data.isAccessRestricted = i->isAccessRestricted(); edge.data.isAccessRestricted = input_edge.isAccessRestricted();
edge.data.edgeBasedNodeID = edges.size();
edge.data.reversedEdge = false; edge.data.reversedEdge = false;
edges.push_back( edge ); edge_list.push_back( edge );
if( edge.data.backward ) { if( edge.data.backward ) {
std::swap( edge.source, edge.target ); std::swap( edge.source, edge.target );
edge.data.forward = i->isBackward(); edge.data.forward = input_edge.isBackward();
edge.data.backward = i->isForward(); edge.data.backward = input_edge.isForward();
edge.data.edgeBasedNodeID = edges.size();
edge.data.reversedEdge = true; edge.data.reversedEdge = true;
edges.push_back( edge ); edge_list.push_back( edge );
} }
} }
std::vector<NodeBasedEdge>().swap(inputEdges); std::vector<NodeBasedEdge>().swap(input_edges);
std::sort( edges.begin(), edges.end() ); BOOST_ASSERT_MSG(
_nodeBasedGraph = boost::make_shared<TarjanDynamicGraph>( nodes, edges ); 0 == input_edges.size() && 0 == input_edges.capacity(),
"input edge vector not properly deallocated"
);
std::sort( edge_list.begin(), edge_list.end() );
m_node_based_graph = boost::make_shared<TarjanDynamicGraph>(
number_of_nodes,
edge_list
);
}
~TarjanSCC() {
m_node_based_graph.reset();
} }
void Run() { void Run() {
@ -211,162 +220,203 @@ public:
DeleteFileIfExists("component.shx"); DeleteFileIfExists("component.shx");
DeleteFileIfExists("component.shp"); DeleteFileIfExists("component.shp");
Percent p(_nodeBasedGraph->GetNumberOfNodes()); Percent p(m_node_based_graph->GetNumberOfNodes());
const char *pszDriverName = "ESRI Shapefile";
OGRSFDriver *poDriver;
OGRRegisterAll(); OGRRegisterAll();
poDriver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName( const char *pszDriverName = "ESRI Shapefile";
pszDriverName ); OGRSFDriver * poDriver = OGRSFDriverRegistrar::GetRegistrar()->
if( poDriver == NULL ) GetDriverByName( pszDriverName );
{ if( NULL == poDriver ) {
printf( "%s driver not available.\n", pszDriverName ); throw OSRMException("ESRI Shapefile driver not available");
exit( 1 );
} }
OGRDataSource *poDS; OGRDataSource * poDS = poDriver->CreateDataSource(
"component.shp",
poDS = poDriver->CreateDataSource( "component.shp", NULL ); NULL
if( poDS == NULL ) {
printf( "Creation of output file failed.\n" );
exit( 1 );
}
OGRLayer *poLayer;
poLayer = poDS->CreateLayer( "component", NULL, wkbLineString, NULL );
if( poLayer == NULL ) {
printf( "Layer creation failed.\n" );
exit( 1 );
}
//The following is a hack to distinguish between stuff that happens before the recursive call and stuff that happens after
std::stack<std::pair<bool, TarjanStackFrame> > recursionStack; //true = stuff before, false = stuff after call
std::stack<NodeID> tarjanStack;
std::vector<unsigned> componentsIndex(_nodeBasedGraph->GetNumberOfNodes(), UINT_MAX);
std::vector<NodeID> vectorOfComponentSizes;
std::vector<TarjanNode> tarjanNodes(_nodeBasedGraph->GetNumberOfNodes());
unsigned currentComponent = 0, sizeOfCurrentComponent = 0;
int index = 0;
for(NodeID node = 0, endNodes = _nodeBasedGraph->GetNumberOfNodes(); node < endNodes; ++node) {
if(UINT_MAX == componentsIndex[node]) {
recursionStack.push(std::make_pair(true, TarjanStackFrame(node,node)) );
}
while(!recursionStack.empty()) {
bool beforeRecursion = recursionStack.top().first;
TarjanStackFrame currentFrame = recursionStack.top().second;
NodeID v = currentFrame.v;
// SimpleLogger().Write() << "popping node " << v << (beforeRecursion ? " before " : " after ") << "recursion";
recursionStack.pop();
if(beforeRecursion) {
//Mark frame to handle tail of recursion
recursionStack.push(std::make_pair(false, currentFrame));
//Mark essential information for SCC
tarjanNodes[v].index = index;
tarjanNodes[v].lowlink = index;
tarjanStack.push(v);
tarjanNodes[v].onStack = true;
++index;
// SimpleLogger().Write() << "pushing " << v << " onto tarjan stack, idx[" << v << "]=" << tarjanNodes[v].index << ", lowlink["<< v << "]=" << tarjanNodes[v].lowlink;
//Traverse outgoing edges
for(TarjanDynamicGraph::EdgeIterator e2 = _nodeBasedGraph->BeginEdges(v); e2 < _nodeBasedGraph->EndEdges(v); ++e2) {
TarjanDynamicGraph::NodeIterator vprime = _nodeBasedGraph->GetTarget(e2);
// SimpleLogger().Write() << "traversing edge (" << v << "," << vprime << ")";
if(UINT_MAX == tarjanNodes[vprime].index) {
recursionStack.push(std::make_pair(true,TarjanStackFrame(vprime, v)));
} else {
// SimpleLogger().Write() << "Node " << vprime << " is already explored";
if(tarjanNodes[vprime].onStack) {
unsigned newLowlink = std::min(tarjanNodes[v].lowlink, tarjanNodes[vprime].index);
// SimpleLogger().Write() << "Setting lowlink[" << v << "] from " << tarjanNodes[v].lowlink << " to " << newLowlink;
tarjanNodes[v].lowlink = newLowlink;
// } else {
// SimpleLogger().Write() << "But node " << vprime << " is not on stack";
}
}
}
} else {
// SimpleLogger().Write() << "we are at the end of recursion and checking node " << v;
{ // setting lowlink in its own scope so it does not pollute namespace
// NodeID parent = (UINT_MAX == tarjanNodes[v].parent ? v : tarjanNodes[v].parent );
// SimpleLogger().Write() << "parent=" << currentFrame.parent;
// SimpleLogger().Write() << "tarjanNodes[" << v << "].lowlink=" << tarjanNodes[v].lowlink << ", tarjanNodes[" << currentFrame.parent << "].lowlink=" << tarjanNodes[currentFrame.parent].lowlink;
//Note the index shift by 1 compared to the recursive version
tarjanNodes[currentFrame.parent].lowlink = std::min(tarjanNodes[currentFrame.parent].lowlink, tarjanNodes[v].lowlink);
// SimpleLogger().Write() << "Setting tarjanNodes[" << currentFrame.parent <<"].lowlink=" << tarjanNodes[currentFrame.parent].lowlink;
}
// SimpleLogger().Write() << "tarjanNodes[" << v << "].lowlink=" << tarjanNodes[v].lowlink << ", tarjanNodes[" << v << "].index=" << tarjanNodes[v].index;
//after recursion, lets do cycle checking
//Check if we found a cycle. This is the bottom part of the recursion
if(tarjanNodes[v].lowlink == tarjanNodes[v].index) {
NodeID vprime;
do {
// SimpleLogger().Write() << "identified component " << currentComponent << ": " << tarjanStack.top();
vprime = tarjanStack.top(); tarjanStack.pop();
tarjanNodes[vprime].onStack = false;
componentsIndex[vprime] = currentComponent;
++sizeOfCurrentComponent;
} while( v != vprime);
vectorOfComponentSizes.push_back(sizeOfCurrentComponent);
if(sizeOfCurrentComponent > 1000)
SimpleLogger().Write() << "large component [" << currentComponent << "]=" << sizeOfCurrentComponent;
++currentComponent;
sizeOfCurrentComponent = 0;
}
}
}
}
SimpleLogger().Write() << "identified: " << vectorOfComponentSizes.size() << " many components, marking small components";
int singleCounter = 0;
for(unsigned i = 0; i < vectorOfComponentSizes.size(); ++i){
if(1 == vectorOfComponentSizes[i])
++singleCounter;
}
SimpleLogger().Write() << "identified " << singleCounter << " SCCs of size 1";
uint64_t total_network_distance = 0;
p.reinit(_nodeBasedGraph->GetNumberOfNodes());
for(TarjanDynamicGraph::NodeIterator u = 0; u < _nodeBasedGraph->GetNumberOfNodes(); ++u ) {
p.printIncrement();
for(TarjanDynamicGraph::EdgeIterator e1 = _nodeBasedGraph->BeginEdges(u); e1 < _nodeBasedGraph->EndEdges(u); ++e1) {
if(_nodeBasedGraph->GetEdgeData(e1).reversedEdge) {
continue;
}
TarjanDynamicGraph::NodeIterator v = _nodeBasedGraph->GetTarget(e1);
total_network_distance += 100*ApproximateDistance(
inputNodeInfoList[u].lat,
inputNodeInfoList[u].lon,
inputNodeInfoList[v].lat,
inputNodeInfoList[v].lon
); );
if(_nodeBasedGraph->GetEdgeData(e1).type != SHRT_MAX) { if( NULL == poDS ) {
assert(e1 != UINT_MAX); throw OSRMException("Creation of output file failed");
assert(u != UINT_MAX); }
assert(v != UINT_MAX);
OGRLayer * poLayer = poDS->CreateLayer(
"component",
NULL,
wkbLineString,
NULL
);
if( NULL == poLayer ) {
throw OSRMException("Layer creation failed.");
}
//The following is a hack to distinguish between stuff that happens
//before the recursive call and stuff that happens after
std::stack<std::pair<bool, TarjanStackFrame> > recursion_stack;
//true = stuff before, false = stuff after call
std::stack<NodeID> tarjan_stack;
std::vector<unsigned> components_index(
m_node_based_graph->GetNumberOfNodes(),
UINT_MAX
);
std::vector<NodeID> component_size_vector;
std::vector<TarjanNode> tarjan_node_list(
m_node_based_graph->GetNumberOfNodes()
);
unsigned component_index = 0, size_of_current_component = 0;
int index = 0;
for(
NodeID node = 0, last_node = m_node_based_graph->GetNumberOfNodes();
node < last_node;
++node
) {
if(UINT_MAX == components_index[node]) {
recursion_stack.push(
std::make_pair(true, TarjanStackFrame(node,node))
);
}
while(!recursion_stack.empty()) {
bool before_recursion = recursion_stack.top().first;
TarjanStackFrame currentFrame = recursion_stack.top().second;
NodeID v = currentFrame.v;
recursion_stack.pop();
if(before_recursion) {
//Mark frame to handle tail of recursion
recursion_stack.push(std::make_pair(false, currentFrame));
//Mark essential information for SCC
tarjan_node_list[v].index = index;
tarjan_node_list[v].lowlink = index;
tarjan_stack.push(v);
tarjan_node_list[v].onStack = true;
++index;
//Traverse outgoing edges
for(
TarjanDynamicGraph::EdgeIterator e2 = m_node_based_graph->BeginEdges(v);
e2 < m_node_based_graph->EndEdges(v);
++e2
) {
const TarjanDynamicGraph::NodeIterator vprime =
m_node_based_graph->GetTarget(e2);
if(UINT_MAX == tarjan_node_list[vprime].index) {
recursion_stack.push(
std::make_pair(
true,
TarjanStackFrame(vprime, v)
)
);
} else {
if(
tarjan_node_list[vprime].onStack &&
tarjan_node_list[vprime].index < tarjan_node_list[v].lowlink
) {
tarjan_node_list[v].lowlink = tarjan_node_list[vprime].index;
}
}
}
} else {
tarjan_node_list[currentFrame.parent].lowlink =
std::min(
tarjan_node_list[currentFrame.parent].lowlink,
tarjan_node_list[v].lowlink
);
//after recursion, lets do cycle checking
//Check if we found a cycle. This is the bottom part of the recursion
if(tarjan_node_list[v].lowlink == tarjan_node_list[v].index) {
NodeID vprime;
do {
vprime = tarjan_stack.top(); tarjan_stack.pop();
tarjan_node_list[vprime].onStack = false;
components_index[vprime] = component_index;
++size_of_current_component;
} while( v != vprime);
component_size_vector.push_back(size_of_current_component);
if(size_of_current_component > 1000) {
SimpleLogger().Write() <<
"large component [" << component_index << "]=" <<
size_of_current_component;
}
++component_index;
size_of_current_component = 0;
}
}
}
}
SimpleLogger().Write() <<
"identified: " << component_size_vector.size() <<
" many components, marking small components";
unsigned size_one_counter = 0;
for(unsigned i = 0, end = component_size_vector.size(); i < end; ++i){
if(1 == component_size_vector[i]) {
++size_one_counter;
}
}
SimpleLogger().Write() <<
"identified " << size_one_counter << " SCCs of size 1";
uint64_t total_network_distance = 0;
p.reinit(m_node_based_graph->GetNumberOfNodes());
for(
TarjanDynamicGraph::NodeIterator u = 0, last_u_node = m_node_based_graph->GetNumberOfNodes();
u < last_u_node;
++u
) {
p.printIncrement();
for(
TarjanDynamicGraph::EdgeIterator e1 = m_node_based_graph->BeginEdges(u), last_edge = m_node_based_graph->EndEdges(u);
e1 < last_edge;
++e1
) {
if(!m_node_based_graph->GetEdgeData(e1).reversedEdge) {
continue;
}
const TarjanDynamicGraph::NodeIterator v = m_node_based_graph->GetTarget(e1);
total_network_distance += 100*ApproximateDistance(
m_coordinate_list[u].lat,
m_coordinate_list[u].lon,
m_coordinate_list[v].lat,
m_coordinate_list[v].lon
);
if( SHRT_MAX != m_node_based_graph->GetEdgeData(e1).type ) {
BOOST_ASSERT(e1 != UINT_MAX);
BOOST_ASSERT(u != UINT_MAX);
BOOST_ASSERT(v != UINT_MAX);
const unsigned size_of_containing_component =
std::min(
component_size_vector[components_index[u]],
component_size_vector[components_index[v]]
);
//edges that end on bollard nodes may actually be in two distinct components //edges that end on bollard nodes may actually be in two distinct components
if(std::min(vectorOfComponentSizes[componentsIndex[u]], vectorOfComponentSizes[componentsIndex[v]]) < 10) { if(size_of_containing_component < 10) {
//INFO("(" << inputNodeInfoList[u].lat/COORDINATE_PRECISION << ";" << inputNodeInfoList[u].lon/COORDINATE_PRECISION << ") -> (" << inputNodeInfoList[v].lat/COORDINATE_PRECISION << ";" << inputNodeInfoList[v].lon/COORDINATE_PRECISION << ")");
OGRLineString lineString; OGRLineString lineString;
lineString.addPoint(inputNodeInfoList[u].lon/COORDINATE_PRECISION, inputNodeInfoList[u].lat/COORDINATE_PRECISION); lineString.addPoint(
lineString.addPoint(inputNodeInfoList[v].lon/COORDINATE_PRECISION, inputNodeInfoList[v].lat/COORDINATE_PRECISION); m_coordinate_list[u].lon/COORDINATE_PRECISION,
OGRFeature *poFeature; m_coordinate_list[u].lat/COORDINATE_PRECISION
poFeature = OGRFeature::CreateFeature( poLayer->GetLayerDefn() ); );
lineString.addPoint(
m_coordinate_list[v].lon/COORDINATE_PRECISION,
m_coordinate_list[v].lat/COORDINATE_PRECISION
);
OGRFeature * poFeature = OGRFeature::CreateFeature(
poLayer->GetLayerDefn()
);
poFeature->SetGeometry( &lineString ); poFeature->SetGeometry( &lineString );
if( poLayer->CreateFeature( poFeature ) != OGRERR_NONE ) { if( OGRERR_NONE != poLayer->CreateFeature(poFeature) ) {
throw OSRMException( throw OSRMException(
"Failed to create feature in shapefile." "Failed to create feature in shapefile."
); );
@ -377,39 +427,66 @@ public:
} }
} }
OGRDataSource::DestroyDataSource( poDS ); OGRDataSource::DestroyDataSource( poDS );
std::vector<NodeID>().swap(vectorOfComponentSizes); std::vector<NodeID>().swap(component_size_vector);
std::vector<NodeID>().swap(componentsIndex); BOOST_ASSERT_MSG(
SimpleLogger().Write() << "total network distance: " << (uint64_t)total_network_distance/100/1000. << " km"; 0 == component_size_vector.size() &&
0 == component_size_vector.capacity(),
"component_size_vector not properly deallocated"
);
std::vector<NodeID>().swap(components_index);
BOOST_ASSERT_MSG(
0 == components_index.size() && 0 == components_index.capacity(),
"icomponents_index not properly deallocated"
);
SimpleLogger().Write()
<< "total network distance: " <<
(uint64_t)total_network_distance/100/1000. <<
" km";
} }
private: private:
unsigned CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const { unsigned CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const {
std::pair < NodeID, NodeID > restrictionSource = std::make_pair(u, v); std::pair < NodeID, NodeID > restriction_source = std::make_pair(u, v);
RestrictionMap::const_iterator restrIter = _restrictionMap.find(restrictionSource); RestrictionMap::const_iterator restriction_iterator = m_restriction_map.find(restriction_source);
if (restrIter != _restrictionMap.end()) { if (restriction_iterator != m_restriction_map.end()) {
unsigned index = restrIter->second; const unsigned index = restriction_iterator->second;
BOOST_FOREACH(RestrictionSource restrictionTarget, _restrictionBucketVector.at(index)) { BOOST_FOREACH(
if(restrictionTarget.second) { const RestrictionSource & restriction_target,
return restrictionTarget.first; m_restriction_bucket_list.at(index)
) {
if(restriction_target.second) {
return restriction_target.first;
} }
} }
} }
return UINT_MAX; return UINT_MAX;
} }
bool CheckIfTurnIsRestricted(const NodeID u, const NodeID v, const NodeID w) const {
bool CheckIfTurnIsRestricted(
const NodeID u,
const NodeID v,
const NodeID w
) const {
//only add an edge if turn is not a U-turn except it is the end of dead-end street. //only add an edge if turn is not a U-turn except it is the end of dead-end street.
std::pair < NodeID, NodeID > restrictionSource = std::make_pair(u, v); std::pair < NodeID, NodeID > restriction_source = std::make_pair(u, v);
RestrictionMap::const_iterator restrIter = _restrictionMap.find(restrictionSource); RestrictionMap::const_iterator restriction_iterator = m_restriction_map.find(restriction_source);
if (restrIter != _restrictionMap.end()) { if (restriction_iterator != m_restriction_map.end()) {
unsigned index = restrIter->second; const unsigned index = restriction_iterator->second;
BOOST_FOREACH(RestrictionTarget restrictionTarget, _restrictionBucketVector.at(index)) { BOOST_FOREACH(
if(w == restrictionTarget.first) const restriction_target & restriction_target,
m_restriction_bucket_list.at(index)
) {
if(w == restriction_target.first) {
return true; return true;
} }
} }
}
return false; return false;
} }
void DeleteFileIfExists(const std::string file_name) const { void DeleteFileIfExists(const std::string & file_name) const {
if (boost::filesystem::exists(file_name) ) { if (boost::filesystem::exists(file_name) ) {
boost::filesystem::remove(file_name); boost::filesystem::remove(file_name);
} }

View File

@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 2.6)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
project(OSRM) project(OSRM)
include(FindPackageHandleStandardArgs) include(FindPackageHandleStandardArgs)
set(HUGO "${CMAKE_CURRENT_SOURCE_DIR}")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
include(GetGitRevisionDescription) include(GetGitRevisionDescription)
@ -19,8 +20,8 @@ endif(IS_64_SYSTEM)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/Util/UUID.cpp UUID.cpp.alwaysbuild add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/Util/UUID.cpp UUID.cpp.alwaysbuild
COMMAND ${CMAKE_COMMAND} -P COMMAND ${CMAKE_COMMAND} -DSOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/cmake/UUID-Config.cmake -P ${CMAKE_SOURCE_DIR}/cmake/UUID-Config.cmake
DEPENDS DEPENDS
${CMAKE_SOURCE_DIR}/Util/UUID.cpp.in ${CMAKE_SOURCE_DIR}/Util/UUID.cpp.in
${CMAKE_SOURCE_DIR}/cmake/UUID-Config.cmake ${CMAKE_SOURCE_DIR}/cmake/UUID-Config.cmake

View File

@ -21,52 +21,56 @@
#include "EdgeBasedGraphFactory.h" #include "EdgeBasedGraphFactory.h"
EdgeBasedGraphFactory::EdgeBasedGraphFactory( EdgeBasedGraphFactory::EdgeBasedGraphFactory(
int nodes, std::vector<ImportEdge> & inputEdges, int number_of_nodes,
std::vector<ImportEdge> & input_edge_list,
std::vector<NodeID> & barrier_node_list, std::vector<NodeID> & barrier_node_list,
std::vector<NodeID> & traffic_light_node_list, std::vector<NodeID> & traffic_light_node_list,
std::vector<TurnRestriction> & input_restrictions_list, std::vector<TurnRestriction> & input_restrictions_list,
std::vector<NodeInfo> & inputNodeInfoList, std::vector<NodeInfo> & m_node_info_list,
SpeedProfileProperties speedProfile SpeedProfileProperties speed_profile
) : speedProfile(speedProfile), ) : speed_profile(speed_profile),
m_turn_restrictions_count(0), m_turn_restrictions_count(0),
inputNodeInfoList(inputNodeInfoList) m_node_info_list(m_node_info_list)
{ {
BOOST_FOREACH(const TurnRestriction & restriction, input_restrictions_list) { BOOST_FOREACH(const TurnRestriction & restriction, input_restrictions_list) {
std::pair<NodeID, NodeID> restrictionSource = std::make_pair(restriction.fromNode, restriction.viaNode); std::pair<NodeID, NodeID> restriction_source =
std::make_pair(restriction.fromNode, restriction.viaNode);
unsigned index; unsigned index;
RestrictionMap::iterator restrIter = _restrictionMap.find(restrictionSource); RestrictionMap::iterator restriction_iter = m_restriction_map.find(restriction_source);
if(restrIter == _restrictionMap.end()) { if(restriction_iter == m_restriction_map.end()) {
index = _restrictionBucketVector.size(); index = m_restriction_bucket_list.size();
_restrictionBucketVector.resize(index+1); m_restriction_bucket_list.resize(index+1);
_restrictionMap[restrictionSource] = index; m_restriction_map[restriction_source] = index;
} else { } else {
index = restrIter->second; index = restriction_iter->second;
//Map already contains an is_only_*-restriction //Map already contains an is_only_*-restriction
if(_restrictionBucketVector.at(index).begin()->second) if(m_restriction_bucket_list.at(index).begin()->second) {
continue; continue;
else if(restriction.flags.isOnly){ } else if(restriction.flags.isOnly) {
//We are going to insert an is_only_*-restriction. There can be only one. //We are going to insert an is_only_*-restriction. There can be only one.
m_turn_restrictions_count -= _restrictionBucketVector.at(index).size(); m_turn_restrictions_count -= m_restriction_bucket_list.at(index).size();
_restrictionBucketVector.at(index).clear(); m_restriction_bucket_list.at(index).clear();
} }
} }
++m_turn_restrictions_count; ++m_turn_restrictions_count;
_restrictionBucketVector.at(index).push_back(std::make_pair(restriction.toNode, restriction.flags.isOnly)); m_restriction_bucket_list.at(index).push_back(
std::make_pair( restriction.toNode, restriction.flags.isOnly)
);
} }
_barrierNodes.insert( m_barrier_nodes.insert(
barrier_node_list.begin(), barrier_node_list.begin(),
barrier_node_list.end() barrier_node_list.end()
); );
_trafficLights.insert( m_traffic_lights.insert(
traffic_light_node_list.begin(), traffic_light_node_list.begin(),
traffic_light_node_list.end() traffic_light_node_list.end()
); );
DeallocatingVector< _NodeBasedEdge > edges; DeallocatingVector< NodeBasedEdge > edges_list;
_NodeBasedEdge edge; NodeBasedEdge edge;
BOOST_FOREACH(const ImportEdge & import_edge, inputEdges) { BOOST_FOREACH(const ImportEdge & import_edge, input_edge_list) {
if(!import_edge.isForward()) { if(!import_edge.isForward()) {
edge.source = import_edge.target(); edge.source = import_edge.target();
edge.target = import_edge.source(); edge.target = import_edge.source();
@ -89,139 +93,189 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(
edge.data.nameID = import_edge.name(); edge.data.nameID = import_edge.name();
edge.data.type = import_edge.type(); edge.data.type = import_edge.type();
edge.data.isAccessRestricted = import_edge.isAccessRestricted(); edge.data.isAccessRestricted = import_edge.isAccessRestricted();
edge.data.edgeBasedNodeID = edges.size(); edge.data.edgeBasedNodeID = edges_list.size();
edge.data.contraFlow = import_edge.isContraFlow(); edge.data.contraFlow = import_edge.isContraFlow();
edges.push_back( edge ); edges_list.push_back( edge );
if( edge.data.backward ) { if( edge.data.backward ) {
std::swap( edge.source, edge.target ); std::swap( edge.source, edge.target );
edge.data.forward = import_edge.isBackward(); edge.data.forward = import_edge.isBackward();
edge.data.backward = import_edge.isForward(); edge.data.backward = import_edge.isForward();
edge.data.edgeBasedNodeID = edges.size(); edge.data.edgeBasedNodeID = edges_list.size();
edges.push_back( edge ); edges_list.push_back( edge );
} }
} }
std::vector<ImportEdge>().swap(inputEdges); std::vector<ImportEdge>().swap(input_edge_list);
std::sort( edges.begin(), edges.end() ); std::sort( edges_list.begin(), edges_list.end() );
_nodeBasedGraph = boost::make_shared<_NodeBasedDynamicGraph>( nodes, edges ); m_node_based_graph = boost::make_shared<NodeBasedDynamicGraph>(
number_of_nodes, edges_list
);
} }
void EdgeBasedGraphFactory::GetEdgeBasedEdges(DeallocatingVector< EdgeBasedEdge >& outputEdgeList ) { void EdgeBasedGraphFactory::GetEdgeBasedEdges(
DeallocatingVector< EdgeBasedEdge >& output_edge_list
) {
BOOST_ASSERT_MSG( BOOST_ASSERT_MSG(
0 == outputEdgeList.size(), 0 == output_edge_list.size(),
"Vector is not empty" "Vector is not empty"
); );
edgeBasedEdges.swap(outputEdgeList); m_edge_based_edge_list.swap(output_edge_list);
} }
void EdgeBasedGraphFactory::GetEdgeBasedNodes( std::vector<EdgeBasedNode> & nodes) { void EdgeBasedGraphFactory::GetEdgeBasedNodes( std::vector<EdgeBasedNode> & nodes) {
#ifndef NDEBUG #ifndef NDEBUG
BOOST_FOREACH(const EdgeBasedNode & node, edgeBasedNodes){ BOOST_FOREACH(const EdgeBasedNode & node, m_edge_based_node_list){
assert(node.lat1 != INT_MAX); assert(node.lon1 != INT_MAX); assert(node.lat1 != INT_MAX); assert(node.lon1 != INT_MAX);
assert(node.lat2 != INT_MAX); assert(node.lon2 != INT_MAX); assert(node.lat2 != INT_MAX); assert(node.lon2 != INT_MAX);
} }
#endif #endif
nodes.swap(edgeBasedNodes); nodes.swap(m_edge_based_node_list);
} }
NodeID EdgeBasedGraphFactory::CheckForEmanatingIsOnlyTurn( NodeID EdgeBasedGraphFactory::CheckForEmanatingIsOnlyTurn(
const NodeID u, const NodeID u,
const NodeID v const NodeID v
) const { ) const {
const std::pair < NodeID, NodeID > restrictionSource = std::make_pair(u, v); const std::pair < NodeID, NodeID > restriction_source = std::make_pair(u, v);
RestrictionMap::const_iterator restrIter = _restrictionMap.find(restrictionSource); RestrictionMap::const_iterator restriction_iter = m_restriction_map.find(restriction_source);
if (restrIter != _restrictionMap.end()) { if (restriction_iter != m_restriction_map.end()) {
const unsigned index = restrIter->second; const unsigned index = restriction_iter->second;
BOOST_FOREACH(const RestrictionSource & restrictionTarget, _restrictionBucketVector.at(index)) { BOOST_FOREACH(
if(restrictionTarget.second) { const RestrictionSource & restriction_target,
return restrictionTarget.first; m_restriction_bucket_list.at(index)
) {
if(restriction_target.second) {
return restriction_target.first;
} }
} }
} }
return UINT_MAX; return UINT_MAX;
} }
bool EdgeBasedGraphFactory::CheckIfTurnIsRestricted(const NodeID u, const NodeID v, const NodeID w) const { bool EdgeBasedGraphFactory::CheckIfTurnIsRestricted(
const NodeID u,
const NodeID v,
const NodeID w
) const {
//only add an edge if turn is not a U-turn except it is the end of dead-end street. //only add an edge if turn is not a U-turn except it is the end of dead-end street.
const std::pair < NodeID, NodeID > restrictionSource = std::make_pair(u, v); const std::pair < NodeID, NodeID > restriction_source = std::make_pair(u, v);
RestrictionMap::const_iterator restrIter = _restrictionMap.find(restrictionSource); RestrictionMap::const_iterator restriction_iter = m_restriction_map.find(restriction_source);
if (restrIter != _restrictionMap.end()) { if (restriction_iter != m_restriction_map.end()) {
const unsigned index = restrIter->second; const unsigned index = restriction_iter->second;
BOOST_FOREACH(const RestrictionTarget & restrictionTarget, _restrictionBucketVector.at(index)) { BOOST_FOREACH(
if(w == restrictionTarget.first) const RestrictionTarget & restriction_target,
m_restriction_bucket_list.at(index)
) {
if(w == restriction_target.first) {
return true; return true;
} }
} }
}
return false; return false;
} }
void EdgeBasedGraphFactory::InsertEdgeBasedNode( void EdgeBasedGraphFactory::InsertEdgeBasedNode(
_NodeBasedDynamicGraph::EdgeIterator e1, EdgeIterator e1,
_NodeBasedDynamicGraph::NodeIterator u, NodeIterator u,
_NodeBasedDynamicGraph::NodeIterator v, NodeIterator v,
bool belongsToTinyComponent) { bool belongsToTinyComponent) {
_NodeBasedDynamicGraph::EdgeData & data = _nodeBasedGraph->GetEdgeData(e1); EdgeData & data = m_node_based_graph->GetEdgeData(e1);
EdgeBasedNode currentNode; EdgeBasedNode currentNode;
currentNode.nameID = data.nameID; currentNode.nameID = data.nameID;
currentNode.lat1 = inputNodeInfoList[u].lat; currentNode.lat1 = m_node_info_list[u].lat;
currentNode.lon1 = inputNodeInfoList[u].lon; currentNode.lon1 = m_node_info_list[u].lon;
currentNode.lat2 = inputNodeInfoList[v].lat; currentNode.lat2 = m_node_info_list[v].lat;
currentNode.lon2 = inputNodeInfoList[v].lon; currentNode.lon2 = m_node_info_list[v].lon;
currentNode.belongsToTinyComponent = belongsToTinyComponent; currentNode.belongsToTinyComponent = belongsToTinyComponent;
currentNode.id = data.edgeBasedNodeID; currentNode.id = data.edgeBasedNodeID;
currentNode.ignoreInGrid = data.ignoreInGrid; currentNode.ignoreInGrid = data.ignoreInGrid;
currentNode.weight = data.distance; currentNode.weight = data.distance;
edgeBasedNodes.push_back(currentNode); m_edge_based_node_list.push_back(currentNode);
} }
void EdgeBasedGraphFactory::Run(const char * originalEdgeDataFilename, lua_State *myLuaState) { void EdgeBasedGraphFactory::Run(
Percent p(_nodeBasedGraph->GetNumberOfNodes()); const char * original_edge_data_filename,
int numberOfSkippedTurns(0); lua_State *lua_state
int nodeBasedEdgeCounter(0); ) {
unsigned numberOfOriginalEdges(0); SimpleLogger().Write() << "Identifying components of the road network";
std::ofstream originalEdgeDataOutFile(originalEdgeDataFilename, std::ios::binary);
originalEdgeDataOutFile.write((char*)&numberOfOriginalEdges, sizeof(unsigned));
Percent p(m_node_based_graph->GetNumberOfNodes());
unsigned skipped_turns_counter = 0;
unsigned node_based_edge_counter = 0;
unsigned original_edges_counter = 0;
SimpleLogger().Write() << "Identifying small components"; std::ofstream edge_data_file(
original_edge_data_filename,
std::ios::binary
);
//writes a dummy value that is updated later
edge_data_file.write(
(char*)&original_edges_counter,
sizeof(unsigned)
);
unsigned current_component = 0, current_component_size = 0;
//Run a BFS on the undirected graph and identify small components //Run a BFS on the undirected graph and identify small components
std::queue<std::pair<NodeID, NodeID> > bfsQueue; std::queue<std::pair<NodeID, NodeID> > bfs_queue;
std::vector<unsigned> componentsIndex(_nodeBasedGraph->GetNumberOfNodes(), UINT_MAX); std::vector<unsigned> component_index_list(
std::vector<NodeID> vectorOfComponentSizes; m_node_based_graph->GetNumberOfNodes(),
unsigned currentComponent = 0, sizeOfCurrentComponent = 0; UINT_MAX
);
std::vector<NodeID> component_size_list;
//put unexplorered node with parent pointer into queue //put unexplorered node with parent pointer into queue
for(NodeID node = 0, endNodes = _nodeBasedGraph->GetNumberOfNodes(); node < endNodes; ++node) { for(
if(UINT_MAX == componentsIndex[node]) { NodeID node = 0,
bfsQueue.push(std::make_pair(node, node)); last_node = m_node_based_graph->GetNumberOfNodes();
node < last_node;
++node
) {
if(UINT_MAX == component_index_list[node]) {
bfs_queue.push(std::make_pair(node, node));
//mark node as read //mark node as read
componentsIndex[node] = currentComponent; component_index_list[node] = current_component;
p.printIncrement(); p.printIncrement();
while(!bfsQueue.empty()) { while(!bfs_queue.empty()) {
//fetch element from BFS queue //fetch element from BFS queue
std::pair<NodeID, NodeID> currentQueueItem = bfsQueue.front(); std::pair<NodeID, NodeID> current_queue_item = bfs_queue.front();
bfsQueue.pop(); bfs_queue.pop();
// SimpleLogger().Write() << "sizeof queue: " << bfsQueue.size() << ", sizeOfCurrentComponents: " << sizeOfCurrentComponent << ", settled nodes: " << settledNodes++ << ", max: " << endNodes; // SimpleLogger().Write() << "sizeof queue: " << bfs_queue.size() <<
const NodeID v = currentQueueItem.first; //current node // ", current_component_sizes: " << current_component_size <<
const NodeID u = currentQueueItem.second; //parent //", settled nodes: " << settledNodes++ << ", max: " << endNodes;
const NodeID v = current_queue_item.first; //current node
const NodeID u = current_queue_item.second; //parent
//increment size counter of current component //increment size counter of current component
++sizeOfCurrentComponent; ++current_component_size;
const bool isBollardNode = (_barrierNodes.find(v) != _barrierNodes.end()); const bool is_barrier_node = (m_barrier_nodes.find(v) != m_barrier_nodes.end());
if(!isBollardNode) { if(!is_barrier_node) {
const NodeID onlyToNode = CheckForEmanatingIsOnlyTurn(u, v); const NodeID to_node_of_only_restriction = CheckForEmanatingIsOnlyTurn(u, v);
//relaxieren edge outgoing edge like below where edge-expanded graph //relaxieren edge outgoing edge like below where edge-expanded graph
for(_NodeBasedDynamicGraph::EdgeIterator e2 = _nodeBasedGraph->BeginEdges(v); e2 < _nodeBasedGraph->EndEdges(v); ++e2) { for(
_NodeBasedDynamicGraph::NodeIterator w = _nodeBasedGraph->GetTarget(e2); EdgeIterator e2 = m_node_based_graph->BeginEdges(v);
e2 < m_node_based_graph->EndEdges(v);
++e2
) {
NodeIterator w = m_node_based_graph->GetTarget(e2);
if(onlyToNode != UINT_MAX && w != onlyToNode) { //We are at an only_-restriction but not at the right turn. if(
to_node_of_only_restriction != UINT_MAX &&
w != to_node_of_only_restriction
) {
//We are at an only_-restriction but not at the right turn.
continue; continue;
} }
if( u != w ) { //only add an edge if turn is not a U-turn except it is the end of dead-end street. if( u != w ) {
if (!CheckIfTurnIsRestricted(u, v, w) ) { //only add an edge if turn is not prohibited //only add an edge if turn is not a U-turn except
//insert next (node, parent) only if w has not yet been explored //when it is at the end of a dead-end street.
if(UINT_MAX == componentsIndex[w]) { if (!CheckIfTurnIsRestricted(u, v, w) ) {
//only add an edge if turn is not prohibited
if(UINT_MAX == component_index_list[w]) {
//insert next (node, parent) only if w has
//not yet been explored
//mark node as read //mark node as read
componentsIndex[w] = currentComponent; component_index_list[w] = current_component;
bfsQueue.push(std::make_pair(w,v)); bfs_queue.push(std::make_pair(w,v));
p.printIncrement(); p.printIncrement();
} }
} }
@ -230,142 +284,214 @@ void EdgeBasedGraphFactory::Run(const char * originalEdgeDataFilename, lua_State
} }
} }
//push size into vector //push size into vector
vectorOfComponentSizes.push_back(sizeOfCurrentComponent); component_size_list.push_back(current_component_size);
//reset counters; //reset counters;
sizeOfCurrentComponent = 0; current_component_size = 0;
++currentComponent; ++current_component;
} }
} }
SimpleLogger().Write() << "identified: " << vectorOfComponentSizes.size() << " many components"; SimpleLogger().Write() <<
"identified: " << component_size_list.size() << " many components";
SimpleLogger().Write() <<
"generating edge-expanded nodes";
p.reinit(_nodeBasedGraph->GetNumberOfNodes()); p.reinit(m_node_based_graph->GetNumberOfNodes());
//loop over all edges and generate new set of nodes. //loop over all edges and generate new set of nodes.
for(_NodeBasedDynamicGraph::NodeIterator u = 0; u < _nodeBasedGraph->GetNumberOfNodes(); ++u ) { for(
for(_NodeBasedDynamicGraph::EdgeIterator e1 = _nodeBasedGraph->BeginEdges(u); e1 < _nodeBasedGraph->EndEdges(u); ++e1) { NodeIterator u = 0,
_NodeBasedDynamicGraph::NodeIterator v = _nodeBasedGraph->GetTarget(e1); number_of_nodes = m_node_based_graph->GetNumberOfNodes();
u < number_of_nodes;
++u
) {
p.printIncrement();
for(
EdgeIterator e1 = m_node_based_graph->BeginEdges(u),
last_edge = m_node_based_graph->EndEdges(u);
e1 < last_edge;
++e1
) {
NodeIterator v = m_node_based_graph->GetTarget(e1);
if(_nodeBasedGraph->GetEdgeData(e1).type != SHRT_MAX) { if(m_node_based_graph->GetEdgeData(e1).type != SHRT_MAX) {
assert(e1 != UINT_MAX); BOOST_ASSERT_MSG(e1 != UINT_MAX, "edge id invalid");
assert(u != UINT_MAX); BOOST_ASSERT_MSG(u != UINT_MAX, "souce node invalid");
assert(v != UINT_MAX); BOOST_ASSERT_MSG(v != UINT_MAX, "target node invalid");
//edges that end on bollard nodes may actually be in two distinct components //Note: edges that end on barrier nodes or on a turn restriction
InsertEdgeBasedNode(e1, u, v, (std::min(vectorOfComponentSizes[componentsIndex[u]], vectorOfComponentSizes[componentsIndex[v]]) < 1000) ); //may actually be in two distinct components. We choose the smallest
const unsigned size_of_component = std::min(
component_size_list[component_index_list[u]],
component_size_list[component_index_list[v]]
);
InsertEdgeBasedNode( e1, u, v, size_of_component < 1000 );
} }
} }
} }
std::vector<NodeID>().swap(vectorOfComponentSizes); SimpleLogger().Write()
std::vector<NodeID>().swap(componentsIndex); << "Generated " << m_edge_based_node_list.size() << " nodes in " <<
"edge-expanded graph";
SimpleLogger().Write() <<
"generating edge-expanded edges";
std::vector<NodeID>().swap(component_size_list);
BOOST_ASSERT_MSG(
0 == component_size_list.capacity(),
"component size vector not deallocated"
);
std::vector<NodeID>().swap(component_index_list);
BOOST_ASSERT_MSG(
0 == component_index_list.capacity(),
"component index vector not deallocated"
);
std::vector<OriginalEdgeData> original_edge_data_vector; std::vector<OriginalEdgeData> original_edge_data_vector;
original_edge_data_vector.reserve(10000); original_edge_data_vector.reserve(10000);
//Loop over all turns and generate new set of edges. //Loop over all turns and generate new set of edges.
//Three nested loop look super-linear, but we are dealing with a linear number of turns only. //Three nested loop look super-linear, but we are dealing with a (kind of)
for(_NodeBasedDynamicGraph::NodeIterator u = 0; u < _nodeBasedGraph->GetNumberOfNodes(); ++u ) { //linear number of turns only.
for(_NodeBasedDynamicGraph::EdgeIterator e1 = _nodeBasedGraph->BeginEdges(u); e1 < _nodeBasedGraph->EndEdges(u); ++e1) { p.reinit(m_node_based_graph->GetNumberOfNodes());
++nodeBasedEdgeCounter; for(
_NodeBasedDynamicGraph::NodeIterator v = _nodeBasedGraph->GetTarget(e1); NodeIterator u = 0,
bool isBollardNode = (_barrierNodes.find(v) != _barrierNodes.end()); last_node = m_node_based_graph->GetNumberOfNodes();
//EdgeWeight heightPenalty = ComputeHeightPenalty(u, v); u < last_node;
NodeID onlyToNode = CheckForEmanatingIsOnlyTurn(u, v); ++u
for(_NodeBasedDynamicGraph::EdgeIterator e2 = _nodeBasedGraph->BeginEdges(v); e2 < _nodeBasedGraph->EndEdges(v); ++e2) { ) {
const _NodeBasedDynamicGraph::NodeIterator w = _nodeBasedGraph->GetTarget(e2); for(
EdgeIterator e1 = m_node_based_graph->BeginEdges(u),
if(onlyToNode != UINT_MAX && w != onlyToNode) { //We are at an only_-restriction but not at the right turn. last_edge_u = m_node_based_graph->EndEdges(u);
++numberOfSkippedTurns; e1 < last_edge_u;
++e1
) {
++node_based_edge_counter;
NodeIterator v = m_node_based_graph->GetTarget(e1);
bool is_barrier_node = (m_barrier_nodes.find(v) != m_barrier_nodes.end());
NodeID to_node_of_only_restriction = CheckForEmanatingIsOnlyTurn(u, v);
for(
EdgeIterator e2 = m_node_based_graph->BeginEdges(v),
last_edge_v = m_node_based_graph->EndEdges(v);
e2 < last_edge_v;
++e2
) {
const NodeIterator w = m_node_based_graph->GetTarget(e2);
if(
to_node_of_only_restriction != UINT_MAX &&
w != to_node_of_only_restriction
) {
//We are at an only_-restriction but not at the right turn.
++skipped_turns_counter;
continue; continue;
} }
if(u == w && 1 != _nodeBasedGraph->GetOutDegree(v) ) { if(u == w && 1 != m_node_based_graph->GetOutDegree(v) ) {
continue; continue;
} }
if( !isBollardNode ) { //only add an edge if turn is not a U-turn except it is the end of dead-end street. if( !is_barrier_node ) {
if (!CheckIfTurnIsRestricted(u, v, w) || (onlyToNode != UINT_MAX && w == onlyToNode)) { //only add an edge if turn is not prohibited //only add an edge if turn is not a U-turn except when it is
const _NodeBasedDynamicGraph::EdgeData edgeData1 = _nodeBasedGraph->GetEdgeData(e1); //at the end of a dead-end street
const _NodeBasedDynamicGraph::EdgeData edgeData2 = _nodeBasedGraph->GetEdgeData(e2); if (
assert(edgeData1.edgeBasedNodeID < _nodeBasedGraph->GetNumberOfEdges()); !CheckIfTurnIsRestricted(u, v, w) ||
assert(edgeData2.edgeBasedNodeID < _nodeBasedGraph->GetNumberOfEdges()); (to_node_of_only_restriction != UINT_MAX && w == to_node_of_only_restriction)
) { //only add an edge if turn is not prohibited
const EdgeData edge_data1 = m_node_based_graph->GetEdgeData(e1);
const EdgeData edge_data2 = m_node_based_graph->GetEdgeData(e2);
assert(edge_data1.edgeBasedNodeID < m_node_based_graph->GetNumberOfEdges());
assert(edge_data2.edgeBasedNodeID < m_node_based_graph->GetNumberOfEdges());
if(!edgeData1.forward || !edgeData2.forward) { if(!edge_data1.forward || !edge_data2.forward) {
continue; continue;
} }
unsigned distance = edgeData1.distance; unsigned distance = edge_data1.distance;
if(_trafficLights.find(v) != _trafficLights.end()) { if(m_traffic_lights.find(v) != m_traffic_lights.end()) {
distance += speedProfile.trafficSignalPenalty; distance += speed_profile.trafficSignalPenalty;
} }
unsigned penalty = GetTurnPenalty(u, v, w, myLuaState); const unsigned penalty =
GetTurnPenalty(u, v, w, lua_state);
TurnInstruction turnInstruction = AnalyzeTurn(u, v, w); TurnInstruction turnInstruction = AnalyzeTurn(u, v, w);
if(turnInstruction == TurnInstructions.UTurn) if(turnInstruction == TurnInstructions.UTurn){
distance += speedProfile.uTurnPenalty; distance += speed_profile.uTurnPenalty;
// if(!edgeData1.isAccessRestricted && edgeData2.isAccessRestricted) { }
// distance += TurnInstructions.AccessRestrictionPenalty;
// turnInstruction |= TurnInstructions.AccessRestrictionFlag;
// }
distance += penalty; distance += penalty;
assert(edge_data1.edgeBasedNodeID != edge_data2.edgeBasedNodeID);
//distance += heightPenalty; original_edge_data_vector.push_back(
//distance += ComputeTurnPenalty(u, v, w); OriginalEdgeData(
assert(edgeData1.edgeBasedNodeID != edgeData2.edgeBasedNodeID); v,
OriginalEdgeData oed(v,edgeData2.nameID, turnInstruction); edge_data2.nameID,
original_edge_data_vector.push_back(oed); turnInstruction
++numberOfOriginalEdges; )
);
++original_edges_counter;
if(original_edge_data_vector.size() > 100000) { if(original_edge_data_vector.size() > 100000) {
originalEdgeDataOutFile.write((char*)&(original_edge_data_vector[0]), original_edge_data_vector.size()*sizeof(OriginalEdgeData)); edge_data_file.write(
(char*)&(original_edge_data_vector[0]),
original_edge_data_vector.size()*sizeof(OriginalEdgeData)
);
original_edge_data_vector.clear(); original_edge_data_vector.clear();
} }
EdgeBasedEdge newEdge(edgeData1.edgeBasedNodeID, edgeData2.edgeBasedNodeID, edgeBasedEdges.size(), distance, true, false ); m_edge_based_edge_list.push_back(
edgeBasedEdges.push_back(newEdge); EdgeBasedEdge(
edge_data1.edgeBasedNodeID,
edge_data2.edgeBasedNodeID,
m_edge_based_edge_list.size(),
distance,
true,
false
)
);
} else { } else {
++numberOfSkippedTurns; ++skipped_turns_counter;
} }
} }
} }
} }
p.printIncrement(); p.printIncrement();
} }
originalEdgeDataOutFile.write((char*)&(original_edge_data_vector[0]), original_edge_data_vector.size()*sizeof(OriginalEdgeData)); edge_data_file.write(
originalEdgeDataOutFile.seekp(std::ios::beg); (char*)&(original_edge_data_vector[0]),
originalEdgeDataOutFile.write((char*)&numberOfOriginalEdges, sizeof(unsigned)); original_edge_data_vector.size()*sizeof(OriginalEdgeData)
originalEdgeDataOutFile.close(); );
edge_data_file.seekp(std::ios::beg);
edge_data_file.write(
(char*)&original_edges_counter,
sizeof(unsigned)
);
edge_data_file.close();
// SimpleLogger().Write() <<"Sorting edge-based Nodes"; SimpleLogger().Write() <<
// std::sort(edgeBasedNodes.begin(), edgeBasedNodes.end(); "Generated " << m_edge_based_node_list.size() << " edge based nodes";
// SimpleLogger().Write() <<"Removing duplicate nodes (if any)"; SimpleLogger().Write() <<
// edgeBasedNodes.erase( std::unique(edgeBasedNodes.begin(), edgeBasedNodes.end()), edgeBasedNodes.end() ); "Node-based graph contains " << node_based_edge_counter << " edges";
// SimpleLogger().Write() <<"Applying vector self-swap trick to free up memory"; SimpleLogger().Write() <<
// SimpleLogger().Write() <<"size: " << edgeBasedNodes.size() << ", cap: " << edgeBasedNodes.capacity(); "Edge-expanded graph ...";
// std::vector<EdgeBasedNode>(edgeBasedNodes).swap(edgeBasedNodes); SimpleLogger().Write() <<
// SimpleLogger().Write() <<"size: " << edgeBasedNodes.size() << ", cap: " << edgeBasedNodes.capacity(); " contains " << m_edge_based_edge_list.size() << " edges";
SimpleLogger().Write() <<"Node-based graph contains " << nodeBasedEdgeCounter << " edges"; SimpleLogger().Write() <<
SimpleLogger().Write() <<"Edge-based graph contains " << edgeBasedEdges.size() << " edges"; " skips " << skipped_turns_counter << " turns, "
// SimpleLogger().Write() << "Edge-based graph contains " << edgeBasedEdges.size() << " edges, blowup is " << 2*((double)edgeBasedEdges.size()/(double)nodeBasedEdgeCounter; "defined by " << m_turn_restrictions_count << " restrictions";
SimpleLogger().Write() <<"Edge-based graph skipped " << numberOfSkippedTurns << " turns, defined by " << numberOfTurnRestrictions << " restrictions.";
SimpleLogger().Write() <<"Generated " << edgeBasedNodes.size() << " edge based nodes";
} }
int EdgeBasedGraphFactory::GetTurnPenalty( int EdgeBasedGraphFactory::GetTurnPenalty(
const NodeID u, const NodeID u,
const NodeID v, const NodeID v,
const NodeID w, const NodeID w,
lua_State *myLuaState lua_State *lua_state
) const { ) const {
const double angle = GetAngleBetweenTwoEdges( const double angle = GetAngleBetweenThreeFixedPointCoordinates (
inputNodeInfoList[u], m_node_info_list[u],
inputNodeInfoList[v], m_node_info_list[v],
inputNodeInfoList[w] m_node_info_list[w]
); );
if( speedProfile.has_turn_penalty_function ) { if( speed_profile.has_turn_penalty_function ) {
try { try {
//call lua profile to compute turn penalty //call lua profile to compute turn penalty
return luabind::call_function<int>( return luabind::call_function<int>(
myLuaState, lua_state,
"turn_function", "turn_function",
180.-angle 180.-angle
); );
@ -381,17 +507,15 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(
const NodeID v, const NodeID v,
const NodeID w const NodeID w
) const { ) const {
const double angle = GetAngleBetweenTwoEdges(inputNodeInfoList[u], inputNodeInfoList[v], inputNodeInfoList[w]);
if(u == w) { if(u == w) {
return TurnInstructions.UTurn; return TurnInstructions.UTurn;
} }
_NodeBasedDynamicGraph::EdgeIterator edge1 = _nodeBasedGraph->FindEdge(u, v); EdgeIterator edge1 = m_node_based_graph->FindEdge(u, v);
_NodeBasedDynamicGraph::EdgeIterator edge2 = _nodeBasedGraph->FindEdge(v, w); EdgeIterator edge2 = m_node_based_graph->FindEdge(v, w);
_NodeBasedDynamicGraph::EdgeData & data1 = _nodeBasedGraph->GetEdgeData(edge1); EdgeData & data1 = m_node_based_graph->GetEdgeData(edge1);
_NodeBasedDynamicGraph::EdgeData & data2 = _nodeBasedGraph->GetEdgeData(edge2); EdgeData & data2 = m_node_based_graph->GetEdgeData(edge2);
if(!data1.contraFlow && data2.contraFlow) { if(!data1.contraFlow && data2.contraFlow) {
return TurnInstructions.EnterAgainstAllowedDirection; return TurnInstructions.EnterAgainstAllowedDirection;
@ -403,7 +527,7 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(
//roundabouts need to be handled explicitely //roundabouts need to be handled explicitely
if(data1.roundabout && data2.roundabout) { if(data1.roundabout && data2.roundabout) {
//Is a turn possible? If yes, we stay on the roundabout! //Is a turn possible? If yes, we stay on the roundabout!
if( 1 == (_nodeBasedGraph->EndEdges(v) - _nodeBasedGraph->BeginEdges(v)) ) { if( 1 == m_node_based_graph->GetOutDegree(v) ) {
//No turn possible. //No turn possible.
return TurnInstructions.NoTurn; return TurnInstructions.NoTurn;
} }
@ -421,31 +545,27 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(
} }
} }
//If street names stay the same and if we are certain that it is not a roundabout, we skip it. //If street names stay the same and if we are certain that it is not a
if( (data1.nameID == data2.nameID) && (0 != data1.nameID)) { //a segment of a roundabout, we skip it.
if( data1.nameID == data2.nameID ) {
//TODO: Here we should also do a small graph exploration to check for
// more complex situations
if( 0 != data1.nameID ) {
return TurnInstructions.NoTurn;
} else if (m_node_based_graph->GetOutDegree(v) <= 2) {
return TurnInstructions.NoTurn; return TurnInstructions.NoTurn;
} }
if( (data1.nameID == data2.nameID) && (0 == data1.nameID) && (_nodeBasedGraph->GetOutDegree(v) <= 2) ) {
return TurnInstructions.NoTurn;
} }
const double angle = GetAngleBetweenThreeFixedPointCoordinates (
m_node_info_list[u],
m_node_info_list[v],
m_node_info_list[w]
);
return TurnInstructions.GetTurnDirectionOfInstruction(angle); return TurnInstructions.GetTurnDirectionOfInstruction(angle);
} }
unsigned EdgeBasedGraphFactory::GetNumberOfNodes() const { unsigned EdgeBasedGraphFactory::GetNumberOfNodes() const {
return _nodeBasedGraph->GetNumberOfEdges(); return m_node_based_graph->GetNumberOfEdges();
}
/* Get angle of line segment (A,C)->(C,B), atan2 magic, formerly cosine theorem*/
template<class CoordinateT>
double EdgeBasedGraphFactory::GetAngleBetweenTwoEdges(const CoordinateT& A, const CoordinateT& C, const CoordinateT& B) const {
const double v1x = (A.lon - C.lon)/COORDINATE_PRECISION;
const double v1y = lat2y(A.lat/COORDINATE_PRECISION) - lat2y(C.lat/COORDINATE_PRECISION);
const double v2x = (B.lon - C.lon)/COORDINATE_PRECISION;
const double v2y = lat2y(B.lat/COORDINATE_PRECISION) - lat2y(C.lat/COORDINATE_PRECISION);
double angle = (atan2(v2y,v2x) - atan2(v1y,v1x) )*180/M_PI;
while(angle < 0)
angle += 360;
return angle;
} }

View File

@ -18,9 +18,7 @@
or see http://www.gnu.org/licenses/agpl.txt. or see http://www.gnu.org/licenses/agpl.txt.
*/ */
/* // This class constructs the edge-expanded routing graph
* This class constructs the edge base representation of a graph from a given node based edge list
*/
#ifndef EDGEBASEDGRAPHFACTORY_H_ #ifndef EDGEBASEDGRAPHFACTORY_H_
#define EDGEBASEDGRAPHFACTORY_H_ #define EDGEBASEDGRAPHFACTORY_H_
@ -31,15 +29,12 @@
#include "../Extractor/ExtractorStructs.h" #include "../Extractor/ExtractorStructs.h"
#include "../DataStructures/HashTable.h" #include "../DataStructures/HashTable.h"
#include "../DataStructures/ImportEdge.h" #include "../DataStructures/ImportEdge.h"
#include "../DataStructures/MercatorUtil.h"
#include "../DataStructures/QueryEdge.h" #include "../DataStructures/QueryEdge.h"
#include "../DataStructures/Percent.h" #include "../DataStructures/Percent.h"
#include "../DataStructures/TurnInstructions.h" #include "../DataStructures/TurnInstructions.h"
#include "../Util/LuaUtil.h" #include "../Util/LuaUtil.h"
#include "../Util/SimpleLogger.h" #include "../Util/SimpleLogger.h"
#include <stxxl.h>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/make_shared.hpp> #include <boost/make_shared.hpp>
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
@ -47,9 +42,8 @@
#include <boost/unordered_map.hpp> #include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp> #include <boost/unordered_set.hpp>
#include <cstdlib>
#include <algorithm> #include <algorithm>
#include <fstream>
#include <queue> #include <queue>
#include <vector> #include <vector>
@ -67,6 +61,7 @@ public:
weight(UINT_MAX >> 1), weight(UINT_MAX >> 1),
ignoreInGrid(false) ignoreInGrid(false)
{ } { }
bool operator<(const EdgeBasedNode & other) const { bool operator<(const EdgeBasedNode & other) const {
return other.id < id; return other.id < id;
} }
@ -100,33 +95,47 @@ public:
}; };
struct SpeedProfileProperties{ struct SpeedProfileProperties{
SpeedProfileProperties() : trafficSignalPenalty(0), uTurnPenalty(0), has_turn_penalty_function(false) {} SpeedProfileProperties() :
trafficSignalPenalty(0),
uTurnPenalty(0),
has_turn_penalty_function(false)
{ }
int trafficSignalPenalty; int trafficSignalPenalty;
int uTurnPenalty; int uTurnPenalty;
bool has_turn_penalty_function; bool has_turn_penalty_function;
} speedProfile; } speed_profile;
explicit EdgeBasedGraphFactory( explicit EdgeBasedGraphFactory(
int nodes, int number_of_nodes,
std::vector<ImportEdge> & inputEdges, std::vector<ImportEdge> & input_edge_list,
std::vector<NodeID> & _bollardNodes, std::vector<NodeID> & barrier_node_list,
std::vector<NodeID> & trafficLights, std::vector<NodeID> & traffic_light_node_list,
std::vector<TurnRestriction> & inputRestrictions, std::vector<TurnRestriction> & input_restrictions_list,
std::vector<NodeInfo> & nI, std::vector<NodeInfo> & m_node_info_list,
SpeedProfileProperties speedProfile SpeedProfileProperties speed_profile
); );
void Run(const char * originalEdgeDataFilename, lua_State *myLuaState); void Run(const char * originalEdgeDataFilename, lua_State *myLuaState);
void GetEdgeBasedEdges( DeallocatingVector< EdgeBasedEdge >& edges ); void GetEdgeBasedEdges( DeallocatingVector< EdgeBasedEdge >& edges );
void GetEdgeBasedNodes( std::vector< EdgeBasedNode> & nodes); void GetEdgeBasedNodes( std::vector< EdgeBasedNode> & nodes);
void GetOriginalEdgeData( std::vector<OriginalEdgeData> & originalEdgeData); void GetOriginalEdgeData( std::vector<OriginalEdgeData> & originalEdgeData);
TurnInstruction AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w) const; TurnInstruction AnalyzeTurn(
int GetTurnPenalty(const NodeID u, const NodeID v, const NodeID w, lua_State *myLuaState) const; const NodeID u,
const NodeID v,
const NodeID w
) const;
int GetTurnPenalty(
const NodeID u,
const NodeID v,
const NodeID w,
lua_State *myLuaState
) const;
unsigned GetNumberOfNodes() const; unsigned GetNumberOfNodes() const;
private: private:
struct _NodeBasedEdgeData { struct NodeBasedEdgeData {
int distance; int distance;
unsigned edgeBasedNodeID; unsigned edgeBasedNodeID;
unsigned nameID; unsigned nameID;
@ -151,35 +160,44 @@ private:
unsigned m_turn_restrictions_count; unsigned m_turn_restrictions_count;
typedef DynamicGraph< _NodeBasedEdgeData > _NodeBasedDynamicGraph; typedef DynamicGraph<NodeBasedEdgeData> NodeBasedDynamicGraph;
typedef _NodeBasedDynamicGraph::InputEdge _NodeBasedEdge; typedef NodeBasedDynamicGraph::InputEdge NodeBasedEdge;
std::vector<NodeInfo> inputNodeInfoList; typedef NodeBasedDynamicGraph::NodeIterator NodeIterator;
unsigned numberOfTurnRestrictions; typedef NodeBasedDynamicGraph::EdgeIterator EdgeIterator;
typedef NodeBasedDynamicGraph::EdgeData EdgeData;
boost::shared_ptr<_NodeBasedDynamicGraph> _nodeBasedGraph;
boost::unordered_set<NodeID> _barrierNodes;
boost::unordered_set<NodeID> _trafficLights;
typedef std::pair<NodeID, NodeID> RestrictionSource; typedef std::pair<NodeID, NodeID> RestrictionSource;
typedef std::pair<NodeID, bool> RestrictionTarget; typedef std::pair<NodeID, bool> RestrictionTarget;
typedef std::vector<RestrictionTarget> EmanatingRestrictionsVector; typedef std::vector<RestrictionTarget> EmanatingRestrictionsVector;
typedef boost::unordered_map<RestrictionSource, unsigned > RestrictionMap; typedef boost::unordered_map<RestrictionSource, unsigned > RestrictionMap;
std::vector<EmanatingRestrictionsVector> _restrictionBucketVector;
RestrictionMap _restrictionMap;
DeallocatingVector<EdgeBasedEdge> edgeBasedEdges; std::vector<NodeInfo> m_node_info_list;
std::vector<EdgeBasedNode> edgeBasedNodes; std::vector<EmanatingRestrictionsVector> m_restriction_bucket_list;
std::vector<EdgeBasedNode> m_edge_based_node_list;
DeallocatingVector<EdgeBasedEdge> m_edge_based_edge_list;
boost::shared_ptr<NodeBasedDynamicGraph> m_node_based_graph;
boost::unordered_set<NodeID> m_barrier_nodes;
boost::unordered_set<NodeID> m_traffic_lights;
RestrictionMap m_restriction_map;
NodeID CheckForEmanatingIsOnlyTurn(
const NodeID u,
const NodeID v
) const;
bool CheckIfTurnIsRestricted(
const NodeID u,
const NodeID v,
const NodeID w
) const;
NodeID CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const;
bool CheckIfTurnIsRestricted(const NodeID u, const NodeID v, const NodeID w) const;
void InsertEdgeBasedNode( void InsertEdgeBasedNode(
_NodeBasedDynamicGraph::EdgeIterator e1, NodeBasedDynamicGraph::EdgeIterator e1,
_NodeBasedDynamicGraph::NodeIterator u, NodeBasedDynamicGraph::NodeIterator u,
_NodeBasedDynamicGraph::NodeIterator v, NodeBasedDynamicGraph::NodeIterator v,
bool belongsToTinyComponent); bool belongsToTinyComponent);
template<class CoordinateT>
double GetAngleBetweenTwoEdges(const CoordinateT& A, const CoordinateT& C, const CoordinateT& B) const;
}; };
#endif /* EDGEBASEDGRAPHFACTORY_H_ */ #endif /* EDGEBASEDGRAPHFACTORY_H_ */

View File

@ -18,8 +18,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt. or see http://www.gnu.org/licenses/agpl.txt.
*/ */
#ifndef CONCURRENTQUEUE_H_INCLUDED #ifndef CONCURRENTQUEUE_H_
#define CONCURRENTQUEUE_H_INCLUDED #define CONCURRENTQUEUE_H_
#include "../typedefs.h"
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <boost/circular_buffer.hpp> #include <boost/circular_buffer.hpp>
@ -27,57 +29,64 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include <boost/thread/mutex.hpp> #include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp> #include <boost/thread/thread.hpp>
#include "../typedefs.h"
template<typename Data> template<typename Data>
class ConcurrentQueue { class ConcurrentQueue {
typedef typename boost::circular_buffer<Data>::size_type size_t;
public: public:
ConcurrentQueue(const size_t max_size) : internal_queue(max_size) { } ConcurrentQueue(const size_t max_size) : m_internal_queue(max_size) { }
inline void push(Data const& data) { inline void push(const Data & data) {
boost::mutex::scoped_lock lock(m_mutex); boost::mutex::scoped_lock lock(m_mutex);
m_not_full.wait(lock, boost::bind(&ConcurrentQueue<Data>::is_not_full, this)); m_not_full.wait(
internal_queue.push_back(data); lock,
boost::bind(&ConcurrentQueue<Data>::is_not_full, this)
);
m_internal_queue.push_back(data);
lock.unlock(); lock.unlock();
m_not_empty.notify_one(); m_not_empty.notify_one();
} }
inline bool empty() const { inline bool empty() const {
return internal_queue.empty(); return m_internal_queue.empty();
} }
inline void wait_and_pop(Data & popped_value) { inline void wait_and_pop(Data & popped_value) {
boost::mutex::scoped_lock lock(m_mutex); boost::mutex::scoped_lock lock(m_mutex);
m_not_empty.wait(lock, boost::bind(&ConcurrentQueue<Data>::is_not_empty, this)); m_not_empty.wait(
popped_value=internal_queue.front(); lock,
internal_queue.pop_front(); boost::bind(&ConcurrentQueue<Data>::is_not_empty, this)
);
popped_value = m_internal_queue.front();
m_internal_queue.pop_front();
lock.unlock(); lock.unlock();
m_not_full.notify_one(); m_not_full.notify_one();
} }
inline bool try_pop(Data& popped_value) { inline bool try_pop(Data& popped_value) {
boost::mutex::scoped_lock lock(m_mutex); boost::mutex::scoped_lock lock(m_mutex);
if(internal_queue.empty()) { if(m_internal_queue.empty()) {
return false; return false;
} }
popped_value=internal_queue.front(); popped_value=m_internal_queue.front();
internal_queue.pop_front(); m_internal_queue.pop_front();
lock.unlock(); lock.unlock();
m_not_full.notify_one(); m_not_full.notify_one();
return true; return true;
} }
private: private:
boost::circular_buffer<Data> internal_queue; inline bool is_not_empty() const {
return !m_internal_queue.empty();
}
inline bool is_not_full() const {
return m_internal_queue.size() < m_internal_queue.capacity();
}
boost::circular_buffer<Data> m_internal_queue;
boost::mutex m_mutex; boost::mutex m_mutex;
boost::condition m_not_empty; boost::condition m_not_empty;
boost::condition m_not_full; boost::condition m_not_full;
inline bool is_not_empty() const { return internal_queue.size() > 0; }
inline bool is_not_full() const { return internal_queue.size() < internal_queue.capacity(); }
}; };
#endif //#ifndef CONCURRENTQUEUE_H_INCLUDED #endif /* CONCURRENTQUEUE_H_ */

View File

@ -21,6 +21,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef FIXED_POINT_COORDINATE_H_ #ifndef FIXED_POINT_COORDINATE_H_
#define FIXED_POINT_COORDINATE_H_ #define FIXED_POINT_COORDINATE_H_
#include "../DataStructures/MercatorUtil.h"
#include "../Util/StringUtil.h" #include "../Util/StringUtil.h"
#include <cassert> #include <cassert>
@ -35,7 +36,7 @@ struct FixedPointCoordinate {
int lat; int lat;
int lon; int lon;
FixedPointCoordinate () : lat(INT_MIN), lon(INT_MIN) {} FixedPointCoordinate () : lat(INT_MIN), lon(INT_MIN) {}
explicit FixedPointCoordinate (int t, int n) : lat(t) , lon(n) {} explicit FixedPointCoordinate (int lat, int lon) : lat(lat) , lon(lon) {}
void Reset() { void Reset() {
lat = INT_MIN; lat = INT_MIN;
@ -141,4 +142,22 @@ static inline void convertInternalReversedCoordinateToString(const FixedPointCoo
output += " "; output += " ";
} }
/* Get angle of line segment (A,C)->(C,B), atan2 magic, formerly cosine theorem*/
template<class CoordinateT>
static inline double GetAngleBetweenThreeFixedPointCoordinates (
const CoordinateT & A,
const CoordinateT & C,
const CoordinateT & B
) {
const double v1x = (A.lon - C.lon)/COORDINATE_PRECISION;
const double v1y = lat2y(A.lat/COORDINATE_PRECISION) - lat2y(C.lat/COORDINATE_PRECISION);
const double v2x = (B.lon - C.lon)/COORDINATE_PRECISION;
const double v2y = lat2y(B.lat/COORDINATE_PRECISION) - lat2y(C.lat/COORDINATE_PRECISION);
double angle = (atan2(v2y,v2x) - atan2(v1y,v1x) )*180/M_PI;
while(angle < 0)
angle += 360;
return angle;
}
#endif /* FIXED_POINT_COORDINATE_H_ */ #endif /* FIXED_POINT_COORDINATE_H_ */

View File

@ -18,16 +18,17 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt. or see http://www.gnu.org/licenses/agpl.txt.
*/ */
#ifndef EDGE_H #ifndef IMPORT_EDGE_H
#define EDGE_H #define IMPORT_EDGE_H
#include "../Util/OSRMException.h" #include "../Util/OSRMException.h"
#include <cassert> #include "../typedefs.h"
#include <boost/assert.hpp>
class NodeBasedEdge { class NodeBasedEdge {
public:
public:
bool operator< (const NodeBasedEdge& e) const { bool operator< (const NodeBasedEdge& e) const {
if (source() == e.source()) { if (source() == e.source()) {
if (target() == e.target()) { if (target() == e.target()) {
@ -58,9 +59,9 @@ public:
_target(t), _target(t),
_name(n), _name(n),
_weight(w), _weight(w),
_type(ty),
forward(f), forward(f),
backward(b), backward(b),
_type(ty),
_roundabout(ra), _roundabout(ra),
_ignoreInGrid(ig), _ignoreInGrid(ig),
_accessRestricted(ar), _accessRestricted(ar),
@ -75,8 +76,9 @@ public:
NodeID source() const {return _source; } NodeID source() const {return _source; }
NodeID name() const { return _name; } NodeID name() const { return _name; }
EdgeWeight weight() const {return _weight; } EdgeWeight weight() const {return _weight; }
short type() const {
short type() const { assert(_type >= 0); return _type; } BOOST_ASSERT_MSG(_type >= 0, "type of ImportEdge invalid");
return _type; }
bool isBackward() const { return backward; } bool isBackward() const { return backward; }
bool isForward() const { return forward; } bool isForward() const { return forward; }
bool isLocatable() const { return _type != 14; } bool isLocatable() const { return _type != 14; }
@ -85,28 +87,26 @@ public:
bool isAccessRestricted() const { return _accessRestricted; } bool isAccessRestricted() const { return _accessRestricted; }
bool isContraFlow() const { return _contraFlow; } bool isContraFlow() const { return _contraFlow; }
//TODO: names need to be fixed.
NodeID _source; NodeID _source;
NodeID _target; NodeID _target;
NodeID _name; NodeID _name;
EdgeWeight _weight; EdgeWeight _weight;
bool forward;
bool backward;
short _type; short _type;
bool _roundabout; bool forward:1;
bool _ignoreInGrid; bool backward:1;
bool _accessRestricted; bool _roundabout:1;
bool _contraFlow; bool _ignoreInGrid:1;
bool _accessRestricted:1;
bool _contraFlow:1;
private: private:
/** Default constructor. target and weight are set to 0.*/ NodeBasedEdge() { }
NodeBasedEdge() :
_source(0), _target(0), _name(0), _weight(0), forward(0), backward(0), _type(0), _roundabout(false), _ignoreInGrid(false), _accessRestricted(false), _contraFlow(false) { assert(false); } //shall not be used.
}; };
class EdgeBasedEdge { class EdgeBasedEdge {
public:
public:
bool operator< (const EdgeBasedEdge& e) const { bool operator< (const EdgeBasedEdge& e) const {
if (source() == e.source()) { if (source() == e.source()) {
if (target() == e.target()) { if (target() == e.target()) {
@ -141,7 +141,14 @@ public:
m_backward(false) m_backward(false)
{ } { }
explicit EdgeBasedEdge(const NodeID s, const NodeID t, const NodeID v, const EdgeWeight w, const bool f, const bool b) : explicit EdgeBasedEdge(
const NodeID s,
const NodeID t,
const NodeID v,
const EdgeWeight w,
const bool f,
const bool b
) :
m_source(s), m_source(s),
m_target(t), m_target(t),
m_edgeID(v), m_edgeID(v),
@ -156,6 +163,7 @@ public:
NodeID id() const { return m_edgeID; } NodeID id() const { return m_edgeID; }
bool isBackward() const { return m_backward; } bool isBackward() const { return m_backward; }
bool isForward() const { return m_forward; } bool isForward() const { return m_forward; }
private: private:
NodeID m_source; NodeID m_source;
NodeID m_target; NodeID m_target;
@ -167,4 +175,4 @@ private:
typedef NodeBasedEdge ImportEdge; typedef NodeBasedEdge ImportEdge;
#endif // EDGE_H #endif /* IMPORT_EDGE_H */

View File

@ -40,20 +40,23 @@ or see http://www.gnu.org/licenses/agpl.txt.
typedef EdgeBasedGraphFactory::EdgeBasedNode RTreeLeaf; typedef EdgeBasedGraphFactory::EdgeBasedNode RTreeLeaf;
class NodeInformationHelpDesk : boost::noncopyable { class NodeInformationHelpDesk : boost::noncopyable {
public: public:
NodeInformationHelpDesk( NodeInformationHelpDesk(
const std::string & ramIndexInput, const std::string & ram_index_filename,
const std::string & fileIndexInput, const std::string & mem_index_filename,
const std::string & nodes_filename, const std::string & nodes_filename,
const std::string & edges_filename, const std::string & edges_filename,
const unsigned number_of_nodes, const unsigned m_number_of_nodes,
const unsigned check_sum const unsigned m_check_sum
) : number_of_nodes(number_of_nodes), check_sum(check_sum) ) :
m_number_of_nodes(m_number_of_nodes),
m_check_sum(m_check_sum)
{ {
if ( ramIndexInput.empty() ) { if ( ram_index_filename.empty() ) {
throw OSRMException("no ram index file name in server ini"); throw OSRMException("no ram index file name in server ini");
} }
if ( fileIndexInput.empty() ) { if ( mem_index_filename.empty() ) {
throw OSRMException("no mem index file name in server ini"); throw OSRMException("no mem index file name in server ini");
} }
if ( nodes_filename.empty() ) { if ( nodes_filename.empty() ) {
@ -63,47 +66,37 @@ public:
throw OSRMException("no edges file name in server ini"); throw OSRMException("no edges file name in server ini");
} }
read_only_rtree = new StaticRTree<RTreeLeaf>( m_ro_rtree_ptr = new StaticRTree<RTreeLeaf>(
ramIndexInput, ram_index_filename,
fileIndexInput mem_index_filename
); );
BOOST_ASSERT_MSG( BOOST_ASSERT_MSG(
0 == coordinateVector.size(), 0 == m_coordinate_list.size(),
"Coordinate vector not empty" "Coordinate vector not empty"
); );
LoadNodesAndEdges(nodes_filename, edges_filename); LoadNodesAndEdges(nodes_filename, edges_filename);
} }
//Todo: Shared memory mechanism
~NodeInformationHelpDesk() { ~NodeInformationHelpDesk() {
delete read_only_rtree; delete m_ro_rtree_ptr;
} }
inline int getLatitudeOfNode(const unsigned id) const { inline FixedPointCoordinate GetCoordinateOfNode(const unsigned id) const {
const NodeID node = origEdgeData_viaNode.at(id); const NodeID node = m_via_node_list.at(id);
return coordinateVector.at(node).lat; return m_coordinate_list.at(node);
} }
inline int getLongitudeOfNode(const unsigned id) const { inline unsigned GetNameIndexFromEdgeID(const unsigned id) const {
const NodeID node = origEdgeData_viaNode.at(id); return m_name_ID_list.at(id);
return coordinateVector.at(node).lon;
} }
inline unsigned getNameIndexFromEdgeID(const unsigned id) const { inline TurnInstruction GetTurnInstructionForEdgeID(const unsigned id) const {
return origEdgeData_nameID.at(id); return m_turn_instruction_list.at(id);
} }
inline TurnInstruction getTurnInstructionFromEdgeID(const unsigned id) const { inline NodeID GetNumberOfNodes() const {
return origEdgeData_turnInstruction.at(id); return m_number_of_nodes;
}
inline NodeID getNumberOfNodes() const {
return number_of_nodes;
}
inline NodeID getNumberOfNodes2() const {
return coordinateVector.size();
} }
inline bool FindNearestNodeCoordForLatLon( inline bool FindNearestNodeCoordForLatLon(
@ -112,12 +105,12 @@ public:
const unsigned zoom_level = 18 const unsigned zoom_level = 18
) const { ) const {
PhantomNode resulting_phantom_node; PhantomNode resulting_phantom_node;
bool foundNode = FindPhantomNodeForCoordinate( bool found_node = FindPhantomNodeForCoordinate(
input_coordinate, input_coordinate,
resulting_phantom_node, zoom_level resulting_phantom_node, zoom_level
); );
result = resulting_phantom_node.location; result = resulting_phantom_node.location;
return foundNode; return found_node;
} }
inline bool FindPhantomNodeForCoordinate( inline bool FindPhantomNodeForCoordinate(
@ -125,7 +118,7 @@ public:
PhantomNode & resulting_phantom_node, PhantomNode & resulting_phantom_node,
const unsigned zoom_level const unsigned zoom_level
) const { ) const {
return read_only_rtree->FindPhantomNodeForCoordinate( return m_ro_rtree_ptr->FindPhantomNodeForCoordinate(
input_coordinate, input_coordinate,
resulting_phantom_node, resulting_phantom_node,
zoom_level zoom_level
@ -133,7 +126,7 @@ public:
} }
inline unsigned GetCheckSum() const { inline unsigned GetCheckSum() const {
return check_sum; return m_check_sum;
} }
private: private:
@ -157,48 +150,63 @@ private:
throw OSRMException("edges file is empty"); throw OSRMException("edges file is empty");
} }
boost::filesystem::ifstream nodes_input_stream(nodes_file, std::ios::binary); boost::filesystem::ifstream nodes_input_stream(
boost::filesystem::ifstream edges_input_stream(edges_file, std::ios::binary); nodes_file,
std::ios::binary
);
SimpleLogger().Write(logDEBUG) << "Loading node data"; boost::filesystem::ifstream edges_input_stream(
NodeInfo b; edges_file, std::ios::binary
);
SimpleLogger().Write(logDEBUG)
<< "Loading node data";
NodeInfo current_node;
while(!nodes_input_stream.eof()) { while(!nodes_input_stream.eof()) {
nodes_input_stream.read((char *)&b, sizeof(NodeInfo)); nodes_input_stream.read((char *)&current_node, sizeof(NodeInfo));
coordinateVector.push_back(FixedPointCoordinate(b.lat, b.lon)); m_coordinate_list.push_back(
FixedPointCoordinate(
current_node.lat,
current_node.lon
)
);
} }
std::vector<FixedPointCoordinate>(coordinateVector).swap(coordinateVector); std::vector<FixedPointCoordinate>(m_coordinate_list).swap(m_coordinate_list);
nodes_input_stream.close(); nodes_input_stream.close();
SimpleLogger().Write(logDEBUG) << "Loading edge data"; SimpleLogger().Write(logDEBUG)
unsigned numberOfOrigEdges(0); << "Loading edge data";
edges_input_stream.read((char*)&numberOfOrigEdges, sizeof(unsigned)); unsigned number_of_edges = 0;
origEdgeData_viaNode.resize(numberOfOrigEdges); edges_input_stream.read((char*)&number_of_edges, sizeof(unsigned));
origEdgeData_nameID.resize(numberOfOrigEdges); m_via_node_list.resize(number_of_edges);
origEdgeData_turnInstruction.resize(numberOfOrigEdges); m_name_ID_list.resize(number_of_edges);
m_turn_instruction_list.resize(number_of_edges);
OriginalEdgeData deserialized_originalEdgeData; OriginalEdgeData current_edge_data;
for(unsigned i = 0; i < numberOfOrigEdges; ++i) { for(unsigned i = 0; i < number_of_edges; ++i) {
edges_input_stream.read( edges_input_stream.read(
(char*)&(deserialized_originalEdgeData), (char*)&(current_edge_data),
sizeof(OriginalEdgeData) sizeof(OriginalEdgeData)
); );
origEdgeData_viaNode[i] = deserialized_originalEdgeData.viaNode; m_via_node_list[i] = current_edge_data.viaNode;
origEdgeData_nameID[i] = deserialized_originalEdgeData.nameID; m_name_ID_list[i] = current_edge_data.nameID;
origEdgeData_turnInstruction[i] = deserialized_originalEdgeData.turnInstruction; m_turn_instruction_list[i] = current_edge_data.turnInstruction;
} }
edges_input_stream.close(); edges_input_stream.close();
SimpleLogger().Write(logDEBUG) << "Loaded " << numberOfOrigEdges << " orig edges"; SimpleLogger().Write(logDEBUG)
SimpleLogger().Write(logDEBUG) << "Opening NN indices"; << "Loaded " << number_of_edges << " orig edges";
SimpleLogger().Write(logDEBUG)
<< "Opening NN indices";
} }
std::vector<FixedPointCoordinate> coordinateVector; std::vector<FixedPointCoordinate> m_coordinate_list;
std::vector<NodeID> origEdgeData_viaNode; std::vector<NodeID> m_via_node_list;
std::vector<unsigned> origEdgeData_nameID; std::vector<unsigned> m_name_ID_list;
std::vector<TurnInstruction> origEdgeData_turnInstruction; std::vector<TurnInstruction> m_turn_instruction_list;
StaticRTree<EdgeBasedGraphFactory::EdgeBasedNode> * read_only_rtree; StaticRTree<EdgeBasedGraphFactory::EdgeBasedNode> * m_ro_rtree_ptr;
const unsigned number_of_nodes; const unsigned m_number_of_nodes;
const unsigned check_sum; const unsigned m_check_sum;
}; };
#endif /*NODEINFORMATIONHELPDESK_H_*/ #endif /*NODEINFORMATIONHELPDESK_H_*/

View File

@ -18,8 +18,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt. or see http://www.gnu.org/licenses/agpl.txt.
*/ */
#ifndef QUERYEDGE_H_ #ifndef QUERYEDGE_H_
#define QUERYEDGE_H_ #define QUERYEDGE_H_

View File

@ -21,8 +21,12 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef RAWROUTEDATA_H_ #ifndef RAWROUTEDATA_H_
#define RAWROUTEDATA_H_ #define RAWROUTEDATA_H_
#include "../DataStructures/Coordinate.h"
#include "../DataStructures/PhantomNodes.h"
#include "../typedefs.h" #include "../typedefs.h"
#include <vector>
struct _PathData { struct _PathData {
_PathData(NodeID no, unsigned na, unsigned tu, unsigned dur) : node(no), nameID(na), durationOfSegment(dur), turnInstruction(tu) { } _PathData(NodeID no, unsigned na, unsigned tu, unsigned dur) : node(no), nameID(na), durationOfSegment(dur), turnInstruction(tu) { }
NodeID node; NodeID node;

View File

@ -29,14 +29,14 @@ SearchEngine::SearchEngine(
shortestPath(_queryData), shortestPath(_queryData),
alternativePaths(_queryData) alternativePaths(_queryData)
{} {}
SearchEngine::~SearchEngine() {} SearchEngine::~SearchEngine() {}
void SearchEngine::GetCoordinatesForNodeID( void SearchEngine::GetCoordinatesForNodeID(
NodeID id, NodeID id,
FixedPointCoordinate& result FixedPointCoordinate& result
) const { ) const {
result.lat = _queryData.nodeHelpDesk->getLatitudeOfNode(id); result = _queryData.nodeHelpDesk->GetCoordinateOfNode(id);
result.lon = _queryData.nodeHelpDesk->getLongitudeOfNode(id);
} }
void SearchEngine::FindPhantomNodeForCoordinate( void SearchEngine::FindPhantomNodeForCoordinate(
@ -57,13 +57,16 @@ NodeID SearchEngine::GetNameIDForOriginDestinationNodeID(
if(s == t) { if(s == t) {
return 0; return 0;
} }
EdgeID e = _queryData.graph->FindEdge(s, t); EdgeID e = _queryData.graph->FindEdge(s, t);
if(e == UINT_MAX) { if(e == UINT_MAX) {
e = _queryData.graph->FindEdge( t, s ); e = _queryData.graph->FindEdge( t, s );
} }
if(UINT_MAX == e) { if(UINT_MAX == e) {
return 0; return 0;
} }
assert(e != UINT_MAX); assert(e != UINT_MAX);
const QueryEdge::EdgeData ed = _queryData.graph->GetEdgeData(e); const QueryEdge::EdgeData ed = _queryData.graph->GetEdgeData(e);
return ed.id; return ed.id;
@ -86,4 +89,3 @@ SearchEngineHeapPtr SearchEngineData::backwardHeap2;
SearchEngineHeapPtr SearchEngineData::forwardHeap3; SearchEngineHeapPtr SearchEngineData::forwardHeap3;
SearchEngineHeapPtr SearchEngineData::backwardHeap3; SearchEngineHeapPtr SearchEngineData::backwardHeap3;

View File

@ -22,12 +22,12 @@ or see http://www.gnu.org/licenses/agpl.txt.
void SearchEngineData::InitializeOrClearFirstThreadLocalStorage() { void SearchEngineData::InitializeOrClearFirstThreadLocalStorage() {
if(!forwardHeap.get()) { if(!forwardHeap.get()) {
forwardHeap.reset(new QueryHeap(nodeHelpDesk->getNumberOfNodes())); forwardHeap.reset(new QueryHeap(nodeHelpDesk->GetNumberOfNodes()));
} else { } else {
forwardHeap->Clear(); forwardHeap->Clear();
} }
if(!backwardHeap.get()) { if(!backwardHeap.get()) {
backwardHeap.reset(new QueryHeap(nodeHelpDesk->getNumberOfNodes())); backwardHeap.reset(new QueryHeap(nodeHelpDesk->GetNumberOfNodes()));
} else { } else {
backwardHeap->Clear(); backwardHeap->Clear();
} }
@ -35,12 +35,12 @@ void SearchEngineData::InitializeOrClearFirstThreadLocalStorage() {
void SearchEngineData::InitializeOrClearSecondThreadLocalStorage() { void SearchEngineData::InitializeOrClearSecondThreadLocalStorage() {
if(!forwardHeap2.get()) { if(!forwardHeap2.get()) {
forwardHeap2.reset(new QueryHeap(nodeHelpDesk->getNumberOfNodes())); forwardHeap2.reset(new QueryHeap(nodeHelpDesk->GetNumberOfNodes()));
} else { } else {
forwardHeap2->Clear(); forwardHeap2->Clear();
} }
if(!backwardHeap2.get()) { if(!backwardHeap2.get()) {
backwardHeap2.reset(new QueryHeap(nodeHelpDesk->getNumberOfNodes())); backwardHeap2.reset(new QueryHeap(nodeHelpDesk->GetNumberOfNodes()));
} else { } else {
backwardHeap2->Clear(); backwardHeap2->Clear();
} }
@ -48,12 +48,12 @@ void SearchEngineData::InitializeOrClearSecondThreadLocalStorage() {
void SearchEngineData::InitializeOrClearThirdThreadLocalStorage() { void SearchEngineData::InitializeOrClearThirdThreadLocalStorage() {
if(!forwardHeap3.get()) { if(!forwardHeap3.get()) {
forwardHeap3.reset(new QueryHeap(nodeHelpDesk->getNumberOfNodes())); forwardHeap3.reset(new QueryHeap(nodeHelpDesk->GetNumberOfNodes()));
} else { } else {
forwardHeap3->Clear(); forwardHeap3->Clear();
} }
if(!backwardHeap3.get()) { if(!backwardHeap3.get()) {
backwardHeap3.reset(new QueryHeap(nodeHelpDesk->getNumberOfNodes())); backwardHeap3.reset(new QueryHeap(nodeHelpDesk->GetNumberOfNodes()));
} else { } else {
backwardHeap3->Clear(); backwardHeap3->Clear();
} }

View File

@ -21,6 +21,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef STATICGRAPH_H_INCLUDED #ifndef STATICGRAPH_H_INCLUDED
#define STATICGRAPH_H_INCLUDED #define STATICGRAPH_H_INCLUDED
#include "../DataStructures/Percent.h"
#include "../Util/SimpleLogger.h" #include "../Util/SimpleLogger.h"
#include "../typedefs.h" #include "../typedefs.h"

View File

@ -23,8 +23,9 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "../DataStructures/HashTable.h" #include "../DataStructures/HashTable.h"
#include "../DataStructures/PhantomNodes.h" #include "../DataStructures/PhantomNodes.h"
#include "../DataStructures/RawRouteData.h"
#include "../DataStructures/SearchEngine.h" #include "../DataStructures/SearchEngine.h"
#include "../Plugins/RawRouteData.h" #include "../Server/BasicDatastructures.h"
#include "../Util/StringUtil.h" #include "../Util/StringUtil.h"
#include "../typedefs.h" #include "../typedefs.h"

View File

@ -72,9 +72,6 @@ void BaseParser::ParseNodeInLua(ImportNode& n, lua_State* localLuaState) {
} }
void BaseParser::ParseWayInLua(ExtractionWay& w, lua_State* localLuaState) { void BaseParser::ParseWayInLua(ExtractionWay& w, lua_State* localLuaState) {
if(2 > w.path.size()) {
return;
}
luabind::call_function<void>( localLuaState, "way_function", boost::ref(w) ); luabind::call_function<void>( localLuaState, "way_function", boost::ref(w) );
} }

View File

@ -111,7 +111,10 @@ void ExtractionContainers::PrepareData(const std::string & output_file_name, con
restrictionsIT->restriction.toNode = wayStartAndEndEdgeIT->firstStart; restrictionsIT->restriction.toNode = wayStartAndEndEdgeIT->firstStart;
} }
if(UINT_MAX != restrictionsIT->restriction.fromNode && UINT_MAX != restrictionsIT->restriction.toNode) { if(
UINT_MAX != restrictionsIT->restriction.fromNode &&
UINT_MAX != restrictionsIT->restriction.toNode
) {
++usableRestrictionsCounter; ++usableRestrictionsCounter;
} }
++restrictionsIT; ++restrictionsIT;
@ -123,8 +126,15 @@ void ExtractionContainers::PrepareData(const std::string & output_file_name, con
restrictionsOutstream.open(restrictionsFileName.c_str(), std::ios::binary); restrictionsOutstream.open(restrictionsFileName.c_str(), std::ios::binary);
restrictionsOutstream.write((char*)&uuid, sizeof(UUID)); restrictionsOutstream.write((char*)&uuid, sizeof(UUID));
restrictionsOutstream.write((char*)&usableRestrictionsCounter, sizeof(unsigned)); restrictionsOutstream.write((char*)&usableRestrictionsCounter, sizeof(unsigned));
for(restrictionsIT = restrictionsVector.begin(); restrictionsIT != restrictionsVector.end(); ++restrictionsIT) { for(
if(UINT_MAX != restrictionsIT->restriction.fromNode && UINT_MAX != restrictionsIT->restriction.toNode) { restrictionsIT = restrictionsVector.begin();
restrictionsIT != restrictionsVector.end();
++restrictionsIT
) {
if(
UINT_MAX != restrictionsIT->restriction.fromNode &&
UINT_MAX != restrictionsIT->restriction.toNode
) {
restrictionsOutstream.write((char *)&(restrictionsIT->restriction), sizeof(TurnRestriction)); restrictionsOutstream.write((char *)&(restrictionsIT->restriction), sizeof(TurnRestriction));
} }
} }

View File

@ -154,7 +154,7 @@ struct CmpWayByID : public std::binary_function<_WayIDStartAndEndEdge, _WayIDSta
struct Cmp : public std::binary_function<NodeID, NodeID, bool> { struct Cmp : public std::binary_function<NodeID, NodeID, bool> {
typedef NodeID value_type; typedef NodeID value_type;
bool operator () (const NodeID & a, const NodeID & b) const { bool operator () (const NodeID a, const NodeID b) const {
return a < b; return a < b;
} }
value_type max_value() { value_type max_value() {

View File

@ -178,9 +178,9 @@ inline void PBFParser::parseDenseNode(_ThreadData * threadData) {
break; break;
} }
const int keyValue = dense.keys_vals ( denseTagIndex+1 ); const int keyValue = dense.keys_vals ( denseTagIndex+1 );
const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(tagValue).data(); const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(tagValue);
const std::string & value = threadData->PBFprimitiveBlock.stringtable().s(keyValue).data(); const std::string & value = threadData->PBFprimitiveBlock.stringtable().s(keyValue);
extracted_nodes_vector[i].keyVals.insert(std::make_pair(key, value)); extracted_nodes_vector[i].keyVals.emplace(key, value);
denseTagIndex += 2; denseTagIndex += 2;
} }
} }
@ -191,7 +191,7 @@ inline void PBFParser::parseDenseNode(_ThreadData * threadData) {
ParseNodeInLua( n, scriptingEnvironment.getLuaStateForThreadID(omp_get_thread_num()) ); ParseNodeInLua( n, scriptingEnvironment.getLuaStateForThreadID(omp_get_thread_num()) );
} }
BOOST_FOREACH(ImportNode &n, extracted_nodes_vector) { BOOST_FOREACH(const ImportNode &n, extracted_nodes_vector) {
extractor_callbacks->nodeFunction(n); extractor_callbacks->nodeFunction(n);
} }
} }
@ -209,7 +209,8 @@ inline void PBFParser::parseRelation(_ThreadData * threadData) {
return; return;
} }
const OSMPBF::PrimitiveGroup& group = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ); const OSMPBF::PrimitiveGroup& group = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID );
for(int i = 0; i < group.relations_size(); ++i ) {
for(int i = 0, relation_size = group.relations_size(); i < relation_size; ++i ) {
std::string except_tag_string; std::string except_tag_string;
const OSMPBF::Relation& inputRelation = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).relations(i); const OSMPBF::Relation& inputRelation = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).relations(i);
bool isRestriction = false; bool isRestriction = false;
@ -241,8 +242,12 @@ inline void PBFParser::parseRelation(_ThreadData * threadData) {
if(isRestriction) { if(isRestriction) {
int64_t lastRef = 0; int64_t lastRef = 0;
_RawRestrictionContainer currentRestrictionContainer(isOnlyRestriction); _RawRestrictionContainer currentRestrictionContainer(isOnlyRestriction);
for(int rolesIndex = 0; rolesIndex < inputRelation.roles_sid_size(); ++rolesIndex) { for(
std::string role(threadData->PBFprimitiveBlock.stringtable().s( inputRelation.roles_sid( rolesIndex ) ).data()); int rolesIndex = 0, last_role = inputRelation.roles_sid_size();
rolesIndex < last_role;
++rolesIndex
) {
const std::string & role = threadData->PBFprimitiveBlock.stringtable().s( inputRelation.roles_sid( rolesIndex ) );
lastRef += inputRelation.memids(rolesIndex); lastRef += inputRelation.memids(rolesIndex);
if(!("from" == role || "to" == role || "via" == role)) { if(!("from" == role || "to" == role || "via" == role)) {
@ -280,7 +285,6 @@ inline void PBFParser::parseRelation(_ThreadData * threadData) {
break; break;
default: //should not happen default: //should not happen
//cout << "unknown";
assert(false); assert(false);
break; break;
} }
@ -309,17 +313,23 @@ inline void PBFParser::parseWay(_ThreadData * threadData) {
for(int j = 0; j < number_of_keys; ++j) { for(int j = 0; j < number_of_keys; ++j) {
const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(inputWay.keys(j)); const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(inputWay.keys(j));
const std::string & val = threadData->PBFprimitiveBlock.stringtable().s(inputWay.vals(j)); const std::string & val = threadData->PBFprimitiveBlock.stringtable().s(inputWay.vals(j));
parsed_way_vector[i].keyVals.insert(std::make_pair(key, val)); parsed_way_vector[i].keyVals.emplace(key, val);
} }
} }
#pragma omp parallel for schedule ( guided ) #pragma omp parallel for schedule ( guided )
for(int i = 0; i < number_of_ways; ++i) { for(int i = 0; i < number_of_ways; ++i) {
ExtractionWay & w = parsed_way_vector[i]; ExtractionWay & w = parsed_way_vector[i];
if(2 > w.path.size()) {
continue;
}
ParseWayInLua( w, scriptingEnvironment.getLuaStateForThreadID( omp_get_thread_num()) ); ParseWayInLua( w, scriptingEnvironment.getLuaStateForThreadID( omp_get_thread_num()) );
} }
BOOST_FOREACH(ExtractionWay & w, parsed_way_vector) { BOOST_FOREACH(ExtractionWay & w, parsed_way_vector) {
if(2 > w.path.size()) {
continue;
}
extractor_callbacks->wayFunction(w); extractor_callbacks->wayFunction(w);
} }
} }
@ -330,21 +340,21 @@ inline void PBFParser::loadGroup(_ThreadData * threadData) {
#endif #endif
const OSMPBF::PrimitiveGroup& group = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ); const OSMPBF::PrimitiveGroup& group = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID );
threadData->entityTypeIndicator = 0; threadData->entityTypeIndicator = TypeDummy;
if ( group.nodes_size() != 0 ) { if ( 0 != group.nodes_size() ) {
threadData->entityTypeIndicator = TypeNode; threadData->entityTypeIndicator = TypeNode;
} }
if ( group.ways_size() != 0 ) { if ( 0 != group.ways_size() ) {
threadData->entityTypeIndicator = TypeWay; threadData->entityTypeIndicator = TypeWay;
} }
if ( group.relations_size() != 0 ) { if ( 0 != group.relations_size() ) {
threadData->entityTypeIndicator = TypeRelation; threadData->entityTypeIndicator = TypeRelation;
} }
if ( group.has_dense() ) { if ( group.has_dense() ) {
threadData->entityTypeIndicator = TypeDenseNode; threadData->entityTypeIndicator = TypeDenseNode;
assert( group.dense().id_size() != 0 ); assert( 0 != group.dense().id_size() );
} }
assert( threadData->entityTypeIndicator != 0 ); assert( threadData->entityTypeIndicator != TypeDummy );
} }
inline void PBFParser::loadBlock(_ThreadData * threadData) { inline void PBFParser::loadBlock(_ThreadData * threadData) {

View File

@ -44,6 +44,7 @@
class PBFParser : public BaseParser { class PBFParser : public BaseParser {
enum EntityType { enum EntityType {
TypeDummy = 0,
TypeNode = 1, TypeNode = 1,
TypeWay = 2, TypeWay = 2,
TypeRelation = 4, TypeRelation = 4,
@ -53,7 +54,7 @@ class PBFParser : public BaseParser {
struct _ThreadData { struct _ThreadData {
int currentGroupID; int currentGroupID;
int currentEntityID; int currentEntityID;
short entityTypeIndicator; EntityType entityTypeIndicator;
OSMPBF::BlobHeader PBFBlobHeader; OSMPBF::BlobHeader PBFBlobHeader;
OSMPBF::Blob PBFBlob; OSMPBF::Blob PBFBlob;
@ -75,15 +76,15 @@ private:
inline void ReadData(); inline void ReadData();
inline void ParseData(); inline void ParseData();
inline void parseDenseNode (_ThreadData * threadData); inline void parseDenseNode (_ThreadData * threadData);
inline void parseNode(_ThreadData * ); inline void parseNode (_ThreadData * threadData);
inline void parseRelation (_ThreadData * threadData); inline void parseRelation (_ThreadData * threadData);
inline void parseWay (_ThreadData * threadData); inline void parseWay (_ThreadData * threadData);
inline void loadGroup (_ThreadData * threadData); inline void loadGroup (_ThreadData * threadData);
inline void loadBlock (_ThreadData * threadData); inline void loadBlock (_ThreadData * threadData);
inline bool readPBFBlobHeader(std::fstream & stream, _ThreadData * threadData); inline bool readPBFBlobHeader(std::fstream & stream, _ThreadData * threadData);
inline bool unpackZLIB(std::fstream &, _ThreadData * threadData); inline bool unpackZLIB (std::fstream & stream, _ThreadData * threadData);
inline bool unpackLZMA(std::fstream &, _ThreadData * ); inline bool unpackLZMA (std::fstream & stream, _ThreadData * threadData);
inline bool readBlob (std::fstream & stream, _ThreadData * threadData); inline bool readBlob (std::fstream & stream, _ThreadData * threadData);
inline bool readNextBlock (std::fstream & stream, _ThreadData * threadData); inline bool readNextBlock (std::fstream & stream, _ThreadData * threadData);

View File

@ -29,7 +29,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "../Plugins/NearestPlugin.h" #include "../Plugins/NearestPlugin.h"
#include "../Plugins/TimestampPlugin.h" #include "../Plugins/TimestampPlugin.h"
#include "../Plugins/ViaRoutePlugin.h" #include "../Plugins/ViaRoutePlugin.h"
#include "../Plugins/RouteParameters.h" #include "../Server/DataStructures/RouteParameters.h"
#include "../Util/IniFile.h" #include "../Util/IniFile.h"
#include "../Util/InputFileUtil.h" #include "../Util/InputFileUtil.h"
#include "../Util/OSRMException.h" #include "../Util/OSRMException.h"

View File

@ -21,9 +21,9 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef BASEPLUGIN_H_ #ifndef BASEPLUGIN_H_
#define BASEPLUGIN_H_ #define BASEPLUGIN_H_
#include "RouteParameters.h"
#include "../DataStructures/Coordinate.h" #include "../DataStructures/Coordinate.h"
#include "../Server/BasicDatastructures.h" #include "../Server/BasicDatastructures.h"
#include "../Server/DataStructures/RouteParameters.h"
#include <string> #include <string>
#include <vector> #include <vector>

View File

@ -22,7 +22,6 @@ or see http://www.gnu.org/licenses/agpl.txt.
#define HELLOWORLDPLUGIN_H_ #define HELLOWORLDPLUGIN_H_
#include "BasePlugin.h" #include "BasePlugin.h"
#include "RouteParameters.h"
#include <sstream> #include <sstream>

View File

@ -22,7 +22,6 @@ or see http://www.gnu.org/licenses/agpl.txt.
#define LOCATEPLUGIN_H_ #define LOCATEPLUGIN_H_
#include "BasePlugin.h" #include "BasePlugin.h"
#include "RouteParameters.h"
#include "../DataStructures/NodeInformationHelpDesk.h" #include "../DataStructures/NodeInformationHelpDesk.h"
#include "../Server/DataStructures/QueryObjectsStorage.h" #include "../Server/DataStructures/QueryObjectsStorage.h"
#include "../Util/StringUtil.h" #include "../Util/StringUtil.h"

View File

@ -22,7 +22,6 @@ or see http://www.gnu.org/licenses/agpl.txt.
#define NearestPlugin_H_ #define NearestPlugin_H_
#include "BasePlugin.h" #include "BasePlugin.h"
#include "RouteParameters.h"
#include "../DataStructures/NodeInformationHelpDesk.h" #include "../DataStructures/NodeInformationHelpDesk.h"
#include "../Server/DataStructures/QueryObjectsStorage.h" #include "../Server/DataStructures/QueryObjectsStorage.h"

View File

@ -22,7 +22,6 @@ or see http://www.gnu.org/licenses/agpl.txt.
#define TIMESTAMPPLUGIN_H_ #define TIMESTAMPPLUGIN_H_
#include "BasePlugin.h" #include "BasePlugin.h"
#include "RouteParameters.h"
class TimestampPlugin : public BasePlugin { class TimestampPlugin : public BasePlugin {
public: public:

View File

@ -22,7 +22,6 @@ or see http://www.gnu.org/licenses/agpl.txt.
#define VIAROUTEPLUGIN_H_ #define VIAROUTEPLUGIN_H_
#include "BasePlugin.h" #include "BasePlugin.h"
#include "RouteParameters.h"
#include "../Algorithms/ObjectToBase64.h" #include "../Algorithms/ObjectToBase64.h"
#include "../DataStructures/HashTable.h" #include "../DataStructures/HashTable.h"
@ -94,7 +93,7 @@ public:
if(checksumOK && i < routeParameters.hints.size() && "" != routeParameters.hints[i]) { if(checksumOK && i < routeParameters.hints.size() && "" != routeParameters.hints[i]) {
// SimpleLogger().Write() <<"Decoding hint: " << routeParameters.hints[i] << " for location index " << i; // SimpleLogger().Write() <<"Decoding hint: " << routeParameters.hints[i] << " for location index " << i;
DecodeObjectFromBase64(routeParameters.hints[i], phantomNodeVector[i]); DecodeObjectFromBase64(routeParameters.hints[i], phantomNodeVector[i]);
if(phantomNodeVector[i].isValid(nodeHelpDesk->getNumberOfNodes())) { if(phantomNodeVector[i].isValid(nodeHelpDesk->GetNumberOfNodes())) {
// SimpleLogger().Write() << "Decoded hint " << i << " successfully"; // SimpleLogger().Write() << "Decoded hint " << i << " successfully";
continue; continue;
} }

View File

@ -23,7 +23,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef BASICROUTINGINTERFACE_H_ #ifndef BASICROUTINGINTERFACE_H_
#define BASICROUTINGINTERFACE_H_ #define BASICROUTINGINTERFACE_H_
#include "../Plugins/RawRouteData.h" #include "../DataStructures/RawRouteData.h"
#include "../Util/ContainerUtils.h" #include "../Util/ContainerUtils.h"
#include "../Util/SimpleLogger.h" #include "../Util/SimpleLogger.h"
@ -148,7 +148,14 @@ public:
recursionStack.push(std::make_pair(edge.first, middle)); recursionStack.push(std::make_pair(edge.first, middle));
} else { } else {
assert(!ed.shortcut); assert(!ed.shortcut);
unpackedPath.push_back(_PathData(ed.id, _queryData.nodeHelpDesk->getNameIndexFromEdgeID(ed.id), _queryData.nodeHelpDesk->getTurnInstructionFromEdgeID(ed.id), ed.distance) ); unpackedPath.push_back(
_PathData(
ed.id,
_queryData.nodeHelpDesk->GetNameIndexFromEdgeID(ed.id),
_queryData.nodeHelpDesk->GetTurnInstructionForEdgeID(ed.id),
ed.distance
)
);
} }
} }
} }

View File

@ -21,8 +21,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef ROUTE_PARAMETERS_H #ifndef ROUTE_PARAMETERS_H
#define ROUTE_PARAMETERS_H #define ROUTE_PARAMETERS_H
#include "../DataStructures/Coordinate.h" #include "../../DataStructures/Coordinate.h"
#include "../DataStructures/HashTable.h" #include "../../DataStructures/HashTable.h"
#include <boost/fusion/container/vector.hpp> #include <boost/fusion/container/vector.hpp>
#include <boost/fusion/sequence/intrinsic.hpp> #include <boost/fusion/sequence/intrinsic.hpp>

View File

@ -23,8 +23,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "APIGrammar.h" #include "APIGrammar.h"
#include "BasicDatastructures.h" #include "BasicDatastructures.h"
#include "DataStructures/RouteParameters.h"
#include "../Library/OSRM.h" #include "../Library/OSRM.h"
#include "../Plugins/RouteParameters.h"
#include "../Util/SimpleLogger.h" #include "../Util/SimpleLogger.h"
#include "../Util/StringUtil.h" #include "../Util/StringUtil.h"
#include "../typedefs.h" #include "../typedefs.h"
@ -47,25 +47,35 @@ public:
try { try {
std::string request(req.uri); std::string request(req.uri);
{ //This block logs the current request to std out. should be moved to a logging component
time_t ltime; time_t ltime;
struct tm *Tm; struct tm *Tm;
ltime=time(NULL); ltime=time(NULL);
Tm=localtime(&ltime); Tm=localtime(&ltime);
SimpleLogger().Write() << (Tm->tm_mday < 10 ? "0" : "" ) << Tm->tm_mday << "-" << (Tm->tm_mon+1 < 10 ? "0" : "" ) << (Tm->tm_mon+1) << "-" << 1900+Tm->tm_year << " " << (Tm->tm_hour < 10 ? "0" : "" ) << Tm->tm_hour << ":" << (Tm->tm_min < 10 ? "0" : "" ) << Tm->tm_min << ":" << (Tm->tm_sec < 10 ? "0" : "" ) << Tm->tm_sec << " " << SimpleLogger().Write() <<
req.endpoint.to_string() << " " << req.referrer << ( 0 == req.referrer.length() ? "- " :" ") << req.agent << ( 0 == req.agent.length() ? "- " :" ") << req.uri; (Tm->tm_mday < 10 ? "0" : "" ) << Tm->tm_mday << "-" <<
} (Tm->tm_mon+1 < 10 ? "0" : "" ) << (Tm->tm_mon+1) << "-" <<
1900+Tm->tm_year << " " << (Tm->tm_hour < 10 ? "0" : "" ) <<
Tm->tm_hour << ":" << (Tm->tm_min < 10 ? "0" : "" ) <<
Tm->tm_min << ":" << (Tm->tm_sec < 10 ? "0" : "" ) <<
Tm->tm_sec << " " << req.endpoint.to_string() << " " <<
req.referrer << ( 0 == req.referrer.length() ? "- " :" ") <<
req.agent << ( 0 == req.agent.length() ? "- " :" ") << req.uri;
RouteParameters routeParameters; RouteParameters routeParameters;
APIGrammarParser apiParser(&routeParameters); APIGrammarParser apiParser(&routeParameters);
std::string::iterator it = request.begin(); std::string::iterator it = request.begin();
bool result = boost::spirit::qi::parse(it, request.end(), apiParser); const bool result = boost::spirit::qi::parse(
it,
request.end(),
apiParser
);
if ( !result || (it != request.end()) ) { if ( !result || (it != request.end()) ) {
rep = http::Reply::stockReply(http::Reply::badRequest); rep = http::Reply::stockReply(http::Reply::badRequest);
int position = std::distance(request.begin(), it); const int position = std::distance(request.begin(), it);
std::string tmp_position_string; std::string tmp_position_string;
intToString(position, tmp_position_string); intToString(position, tmp_position_string);
rep.content += "Input seems to be malformed close to position "; rep.content += "Input seems to be malformed close to position ";
@ -73,7 +83,7 @@ public:
rep.content += request; rep.content += request;
rep.content += tmp_position_string; rep.content += tmp_position_string;
rep.content += "<br>"; rep.content += "<br>";
unsigned end = std::distance(request.begin(), it); const unsigned end = std::distance(request.begin(), it);
for(unsigned i = 0; i < end; ++i) { for(unsigned i = 0; i < end; ++i) {
rep.content += "&nbsp;"; rep.content += "&nbsp;";
} }

View File

@ -30,6 +30,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "../Util/InputFileUtil.h" #include "../Util/InputFileUtil.h"
#include "../Util/OSRMException.h" #include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h" #include "../Util/SimpleLogger.h"
#include "../Util/UUID.h"
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <fstream> #include <fstream>
@ -58,6 +59,16 @@ int main (int argc, char * argv[]) {
SimpleLogger().Write() << SimpleLogger().Write() <<
"Using restrictions from file: " << argv[2]; "Using restrictions from file: " << argv[2];
std::ifstream restriction_ifstream(argv[2], std::ios::binary); std::ifstream restriction_ifstream(argv[2], std::ios::binary);
const UUID uuid_orig;
UUID uuid_loaded;
restriction_ifstream.read((char *) &uuid_loaded, sizeof(UUID));
if( !uuid_loaded.TestGraphUtil(uuid_orig) ) {
SimpleLogger().Write(logWARNING) <<
argv[2] << " was prepared with a different build. "
"Reprocess to get rid of this warning.";
}
if(!restriction_ifstream.good()) { if(!restriction_ifstream.good()) {
throw OSRMException("Could not access <osrm-restrictions> files"); throw OSRMException("Could not access <osrm-restrictions> files");
} }
@ -92,6 +103,11 @@ int main (int argc, char * argv[]) {
); );
input_stream.close(); input_stream.close();
BOOST_ASSERT_MSG(
restrictions_vector.size() == usable_restriction_count,
"size of restrictions_vector changed"
);
SimpleLogger().Write() << SimpleLogger().Write() <<
restrictions_vector.size() << " restrictions, " << restrictions_vector.size() << " restrictions, " <<
bollard_node_IDs_vector.size() << " bollard nodes, " << bollard_node_IDs_vector.size() << " bollard nodes, " <<

View File

@ -68,21 +68,21 @@ NodeID readBinaryOSRMGraphFromStream(
if( !uuid_loaded.TestGraphUtil(uuid_orig) ) { if( !uuid_loaded.TestGraphUtil(uuid_orig) ) {
SimpleLogger().Write(logWARNING) << SimpleLogger().Write(logWARNING) <<
".osrm was prepared with different build.\n" ".osrm was prepared with different build."
"Reprocess to get rid of this warning."; "Reprocess to get rid of this warning.";
} }
NodeID n, source, target; NodeID n, source, target;
EdgeID m; EdgeID m;
short dir;// direction (0 = open, 1 = forward, 2+ = open) short dir;// direction (0 = open, 1 = forward, 2+ = open)
ExternalNodeMap ext2IntNodeMap; ExternalNodeMap ext_to_int_id_map;
in.read((char*)&n, sizeof(NodeID)); in.read((char*)&n, sizeof(NodeID));
SimpleLogger().Write() << "Importing n = " << n << " nodes "; SimpleLogger().Write() << "Importing n = " << n << " nodes ";
_Node node; _Node node;
for (NodeID i=0; i<n; ++i) { for (NodeID i=0; i<n; ++i) {
in.read((char*)&node, sizeof(_Node)); in.read((char*)&node, sizeof(_Node));
int2ExtNodeMap->push_back(NodeInfo(node.lat, node.lon, node.id)); int2ExtNodeMap->push_back(NodeInfo(node.lat, node.lon, node.id));
ext2IntNodeMap.insert(std::make_pair(node.id, i)); ext_to_int_id_map.emplace(node.id, i);
if(node.bollard) { if(node.bollard) {
bollardNodes.push_back(i); bollardNodes.push_back(i);
} }
@ -97,28 +97,29 @@ NodeID readBinaryOSRMGraphFromStream(
in.read((char*)&m, sizeof(unsigned)); in.read((char*)&m, sizeof(unsigned));
SimpleLogger().Write() << " and " << m << " edges "; SimpleLogger().Write() << " and " << m << " edges ";
for(unsigned i = 0; i < inputRestrictions.size(); ++i) { // for(unsigned i = 0; i < inputRestrictions.size(); ++i) {
ExternalNodeMap::iterator intNodeID = ext2IntNodeMap.find(inputRestrictions[i].fromNode); BOOST_FOREACH(TurnRestriction & current_restriction, inputRestrictions) {
if( intNodeID == ext2IntNodeMap.end()) { ExternalNodeMap::iterator intNodeID = ext_to_int_id_map.find(current_restriction.fromNode);
if( intNodeID == ext_to_int_id_map.end()) {
SimpleLogger().Write(logDEBUG) << "Unmapped from Node of restriction"; SimpleLogger().Write(logDEBUG) << "Unmapped from Node of restriction";
continue; continue;
} }
inputRestrictions[i].fromNode = intNodeID->second; current_restriction.fromNode = intNodeID->second;
intNodeID = ext2IntNodeMap.find(inputRestrictions[i].viaNode); intNodeID = ext_to_int_id_map.find(current_restriction.viaNode);
if( intNodeID == ext2IntNodeMap.end()) { if( intNodeID == ext_to_int_id_map.end()) {
SimpleLogger().Write(logDEBUG) << "Unmapped via node of restriction"; SimpleLogger().Write(logDEBUG) << "Unmapped via node of restriction";
continue; continue;
} }
inputRestrictions[i].viaNode = intNodeID->second; current_restriction.viaNode = intNodeID->second;
intNodeID = ext2IntNodeMap.find(inputRestrictions[i].toNode); intNodeID = ext_to_int_id_map.find(current_restriction.toNode);
if( intNodeID == ext2IntNodeMap.end()) { if( intNodeID == ext_to_int_id_map.end()) {
SimpleLogger().Write(logDEBUG) << "Unmapped to node of restriction"; SimpleLogger().Write(logDEBUG) << "Unmapped to node of restriction";
continue; continue;
} }
inputRestrictions[i].toNode = intNodeID->second; current_restriction.toNode = intNodeID->second;
} }
edgeList.reserve(m); edgeList.reserve(m);
@ -153,8 +154,8 @@ NodeID readBinaryOSRMGraphFromStream(
assert(type >= 0); assert(type >= 0);
// translate the external NodeIDs to internal IDs // translate the external NodeIDs to internal IDs
ExternalNodeMap::iterator intNodeID = ext2IntNodeMap.find(source); ExternalNodeMap::iterator intNodeID = ext_to_int_id_map.find(source);
if( ext2IntNodeMap.find(source) == ext2IntNodeMap.end()) { if( ext_to_int_id_map.find(source) == ext_to_int_id_map.end()) {
#ifndef NDEBUG #ifndef NDEBUG
SimpleLogger().Write(logWARNING) << SimpleLogger().Write(logWARNING) <<
" unresolved source NodeID: " << source; " unresolved source NodeID: " << source;
@ -162,8 +163,8 @@ NodeID readBinaryOSRMGraphFromStream(
continue; continue;
} }
source = intNodeID->second; source = intNodeID->second;
intNodeID = ext2IntNodeMap.find(target); intNodeID = ext_to_int_id_map.find(target);
if(ext2IntNodeMap.find(target) == ext2IntNodeMap.end()) { if(ext_to_int_id_map.find(target) == ext_to_int_id_map.end()) {
#ifndef NDEBUG #ifndef NDEBUG
SimpleLogger().Write(logWARNING) << SimpleLogger().Write(logWARNING) <<
"unresolved target NodeID : " << target; "unresolved target NodeID : " << target;
@ -215,7 +216,7 @@ NodeID readBinaryOSRMGraphFromStream(
} }
} }
typename std::vector<EdgeT>::iterator newEnd = std::remove_if(edgeList.begin(), edgeList.end(), _ExcessRemover<EdgeT>()); typename std::vector<EdgeT>::iterator newEnd = std::remove_if(edgeList.begin(), edgeList.end(), _ExcessRemover<EdgeT>());
ext2IntNodeMap.clear(); ext_to_int_id_map.clear();
std::vector<EdgeT>(edgeList.begin(), newEnd).swap(edgeList); //remove excess candidates. std::vector<EdgeT>(edgeList.begin(), newEnd).swap(edgeList); //remove excess candidates.
SimpleLogger().Write() << "Graph loaded ok and has " << edgeList.size() << " edges"; SimpleLogger().Write() << "Graph loaded ok and has " << edgeList.size() << " edges";
return n; return n;
@ -225,13 +226,13 @@ NodeID readDTMPGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeList, s
NodeID n, source, target, id; NodeID n, source, target, id;
EdgeID m; EdgeID m;
int dir, xcoord, ycoord;// direction (0 = open, 1 = forward, 2+ = open) int dir, xcoord, ycoord;// direction (0 = open, 1 = forward, 2+ = open)
ExternalNodeMap ext2IntNodeMap; ExternalNodeMap ext_to_int_id_map;
in >> n; in >> n;
SimpleLogger().Write(logDEBUG) << "Importing n = " << n << " nodes "; SimpleLogger().Write(logDEBUG) << "Importing n = " << n << " nodes ";
for (NodeID i=0; i<n; ++i) { for (NodeID i=0; i<n; ++i) {
in >> id >> ycoord >> xcoord; in >> id >> ycoord >> xcoord;
int2ExtNodeMap->push_back(NodeInfo(xcoord, ycoord, id)); int2ExtNodeMap->push_back(NodeInfo(xcoord, ycoord, id));
ext2IntNodeMap.insert(std::make_pair(id, i)); ext_to_int_id_map.insert(std::make_pair(id, i));
} }
in >> m; in >> m;
SimpleLogger().Write(logDEBUG) << " and " << m << " edges"; SimpleLogger().Write(logDEBUG) << " and " << m << " edges";
@ -321,13 +322,13 @@ NodeID readDTMPGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeList, s
} }
// translate the external NodeIDs to internal IDs // translate the external NodeIDs to internal IDs
ExternalNodeMap::iterator intNodeID = ext2IntNodeMap.find(source); ExternalNodeMap::iterator intNodeID = ext_to_int_id_map.find(source);
if( ext2IntNodeMap.find(source) == ext2IntNodeMap.end()) { if( ext_to_int_id_map.find(source) == ext_to_int_id_map.end()) {
throw OSRMException("unresolvable source Node ID"); throw OSRMException("unresolvable source Node ID");
} }
source = intNodeID->second; source = intNodeID->second;
intNodeID = ext2IntNodeMap.find(target); intNodeID = ext_to_int_id_map.find(target);
if(ext2IntNodeMap.find(target) == ext2IntNodeMap.end()) { if(ext_to_int_id_map.find(target) == ext_to_int_id_map.end()) {
throw OSRMException("unresolvable target Node ID"); throw OSRMException("unresolvable target Node ID");
} }
target = intNodeID->second; target = intNodeID->second;
@ -339,7 +340,7 @@ NodeID readDTMPGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeList, s
EdgeT inputEdge(source, target, 0, weight, forward, backward, type ); EdgeT inputEdge(source, target, 0, weight, forward, backward, type );
edgeList.push_back(inputEdge); edgeList.push_back(inputEdge);
} }
ext2IntNodeMap.clear(); ext_to_int_id_map.clear();
std::vector<EdgeT>(edgeList.begin(), edgeList.end()).swap(edgeList); //remove excess candidates. std::vector<EdgeT>(edgeList.begin(), edgeList.end()).swap(edgeList); //remove excess candidates.
std::cout << "ok" << std::endl; std::cout << "ok" << std::endl;
return n; return n;

View File

@ -1,12 +1,11 @@
set(oldfile ${CMAKE_SOURCE_DIR}/../Util/UUID.cpp) set(OLDFILE ${SOURCE_DIR}/Util/UUID.cpp)
if (EXISTS ${oldfile}) if (EXISTS ${OLDFILE})
file(REMOVE_RECURSE ${oldfile}) file(REMOVE_RECURSE ${OLDFILE})
endif() endif()
file(MD5 ${SOURCE_DIR}/createHierarchy.cpp MD5PREPARE)
file(MD5 ${SOURCE_DIR}/DataStructures/StaticRTree.h MD5RTREE)
file(MD5 ${SOURCE_DIR}/DataStructures/NodeInformationHelpDesk.h MD5NODEINFO)
file(MD5 ${SOURCE_DIR}/Util/GraphLoader.h MD5GRAPH)
file(MD5 ${SOURCE_DIR}/Server/DataStructures/QueryObjectsStorage.cpp MD5OBJECTS)
file(MD5 ${CMAKE_SOURCE_DIR}/../createHierarchy.cpp MD5PREPARE) CONFIGURE_FILE( ${SOURCE_DIR}/Util/UUID.cpp.in ${SOURCE_DIR}/Util/UUID.cpp )
file(MD5 ${CMAKE_SOURCE_DIR}/../DataStructures/StaticRTree.h MD5RTREE)
file(MD5 ${CMAKE_SOURCE_DIR}/../DataStructures/NodeInformationHelpDesk.h MD5NODEINFO)
file(MD5 ${CMAKE_SOURCE_DIR}/../Util/GraphLoader.h MD5GRAPH)
file(MD5 ${CMAKE_SOURCE_DIR}/../Server/DataStructures/QueryObjectsStorage.cpp MD5OBJECTS)
CONFIGURE_FILE( ${CMAKE_SOURCE_DIR}/../Util/UUID.cpp.in ${CMAKE_SOURCE_DIR}/../Util/UUID.cpp )

View File

@ -85,7 +85,6 @@ function node_function (node)
node.bollard = true node.bollard = true
end end
end end
return 1
end end
@ -93,19 +92,19 @@ function way_function (way)
-- we dont route over areas -- we dont route over areas
local area = way.tags:Find("area") local area = way.tags:Find("area")
if ignore_areas and ("yes" == area) then if ignore_areas and ("yes" == area) then
return 0 return
end end
-- check if oneway tag is unsupported -- check if oneway tag is unsupported
local oneway = way.tags:Find("oneway") local oneway = way.tags:Find("oneway")
if "reversible" == oneway then if "reversible" == oneway then
return 0 return
end end
-- Check if we are allowed to access the way -- Check if we are allowed to access the way
local access = Access.find_access_tag(way, access_tags_hierachy) local access = Access.find_access_tag(way, access_tags_hierachy)
if access_tag_blacklist[access] then if access_tag_blacklist[access] then
return 0 return
end end
-- Second, parse the way according to these properties -- Second, parse the way according to these properties
@ -212,7 +211,7 @@ function way_function (way)
way.ignore_in_grid = true way.ignore_in_grid = true
end end
way.type = 1 way.type = 1
return 1 return
end end
-- These are wrappers to parse vectors of nodes and ways and thus to speed up any tracing JIT -- These are wrappers to parse vectors of nodes and ways and thus to speed up any tracing JIT