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 <boost/assert.hpp>
#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
#include <boost/integer.hpp>
#include <boost/make_shared.hpp>
#include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp>
#ifdef __APPLE__
#include <gdal.h>
@ -48,7 +50,7 @@ Strongly connected components using Tarjan's Algorithm
#include <gdal/gdal.h>
#include <gdal/ogrsf_frmts.h>
#endif
#include <cassert>
#include <stack>
#include <vector>
@ -64,7 +66,6 @@ private:
struct TarjanEdgeData {
int distance;
unsigned edgeBasedNodeID;
unsigned nameID:31;
bool shortcut:1;
short type;
@ -77,7 +78,10 @@ private:
};
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 parent;
};
@ -85,18 +89,17 @@ private:
typedef DynamicGraph<TarjanEdgeData> TarjanDynamicGraph;
typedef TarjanDynamicGraph::InputEdge TarjanEdge;
typedef std::pair<NodeID, NodeID> RestrictionSource;
typedef std::pair<NodeID, bool> RestrictionTarget;
typedef std::vector<RestrictionTarget> EmanatingRestrictionsVector;
typedef std::pair<NodeID, bool> restriction_target;
typedef std::vector<restriction_target> EmanatingRestrictionsVector;
typedef boost::unordered_map<RestrictionSource, unsigned > RestrictionMap;
std::vector<NodeInfo> inputNodeInfoList;
unsigned numberOfTurnRestrictions;
boost::shared_ptr<TarjanDynamicGraph> _nodeBasedGraph;
boost::unordered_map<NodeID, bool> _barrierNodes;
boost::unordered_map<NodeID, bool> _trafficLights;
std::vector<EmanatingRestrictionsVector> _restrictionBucketVector;
RestrictionMap _restrictionMap;
std::vector<NodeInfo> m_coordinate_list;
std::vector<EmanatingRestrictionsVector> m_restriction_bucket_list;
boost::shared_ptr<TarjanDynamicGraph> m_node_based_graph;
boost::unordered_set<NodeID> m_barrier_node_list;
boost::unordered_set<NodeID> m_traffic_light_list;
unsigned m_restriction_counter;
RestrictionMap m_restriction_map;
struct EdgeBasedNode {
bool operator<(const EdgeBasedNode & other) const {
@ -116,93 +119,99 @@ private:
bool ignoreInGrid:1;
};
DeallocatingVector<EdgeBasedNode> edgeBasedNodes;
public:
TarjanSCC(
int nodes,
std::vector<NodeBasedEdge> & inputEdges,
int number_of_nodes,
std::vector<NodeBasedEdge> & input_edges,
std::vector<NodeID> & bn,
std::vector<NodeID> & tl,
std::vector<TurnRestriction> & irs,
std::vector<NodeInfo> & nI
) :
inputNodeInfoList(nI),
numberOfTurnRestrictions(irs.size())
m_coordinate_list(nI),
m_restriction_counter(irs.size())
{
BOOST_FOREACH(const TurnRestriction & restriction, irs) {
std::pair<NodeID, NodeID> restrictionSource = std::make_pair(
restriction.fromNode, restriction.viaNode
);
unsigned index;
RestrictionMap::iterator restrIter = _restrictionMap.find(restrictionSource);
if(restrIter == _restrictionMap.end()) {
index = _restrictionBucketVector.size();
_restrictionBucketVector.resize(index+1);
_restrictionMap[restrictionSource] = index;
RestrictionMap::iterator restriction_iterator = m_restriction_map.find(restrictionSource);
if(restriction_iterator == m_restriction_map.end()) {
index = m_restriction_bucket_list.size();
m_restriction_bucket_list.resize(index+1);
m_restriction_map[restrictionSource] = index;
} else {
index = restrIter->second;
index = restriction_iterator->second;
//Map already contains an is_only_*-restriction
if(_restrictionBucketVector.at(index).begin()->second)
if(m_restriction_bucket_list.at(index).begin()->second) {
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.
_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)
);
}
BOOST_FOREACH(NodeID id, bn) {
_barrierNodes[id] = true;
}
BOOST_FOREACH(NodeID id, tl) {
_trafficLights[id] = true;
}
DeallocatingVector< TarjanEdge > edges;
for ( std::vector< NodeBasedEdge >::const_iterator i = inputEdges.begin(); i != inputEdges.end(); ++i ) {
m_barrier_node_list.insert(bn.begin(), bn.end());
m_traffic_light_list.insert(tl.begin(), tl.end());
DeallocatingVector< TarjanEdge > edge_list;
BOOST_FOREACH(const NodeBasedEdge & input_edge, input_edges) {
TarjanEdge edge;
if(!i->isForward()) {
edge.source = i->target();
edge.target = i->source();
edge.data.backward = i->isForward();
edge.data.forward = i->isBackward();
if(!input_edge.isForward()) {
edge.source = input_edge.target();
edge.target = input_edge.source();
edge.data.backward = input_edge.isForward();
edge.data.forward = input_edge.isBackward();
} else {
edge.source = i->source();
edge.target = i->target();
edge.data.forward = i->isForward();
edge.data.backward = i->isBackward();
edge.source = input_edge.source();
edge.target = input_edge.target();
edge.data.forward = input_edge.isForward();
edge.data.backward = input_edge.isBackward();
}
if(edge.source == edge.target)
if(edge.source == edge.target) {
continue;
}
edge.data.distance = (std::max)((int)i->weight(), 1 );
assert( edge.data.distance > 0 );
edge.data.distance = (std::max)((int)input_edge.weight(), 1 );
BOOST_ASSERT( edge.data.distance > 0 );
edge.data.shortcut = false;
edge.data.roundabout = i->isRoundabout();
edge.data.ignoreInGrid = i->ignoreInGrid();
edge.data.nameID = i->name();
edge.data.type = i->type();
edge.data.isAccessRestricted = i->isAccessRestricted();
edge.data.edgeBasedNodeID = edges.size();
edge.data.roundabout = input_edge.isRoundabout();
edge.data.ignoreInGrid = input_edge.ignoreInGrid();
edge.data.nameID = input_edge.name();
edge.data.type = input_edge.type();
edge.data.isAccessRestricted = input_edge.isAccessRestricted();
edge.data.reversedEdge = false;
edges.push_back( edge );
edge_list.push_back( edge );
if( edge.data.backward ) {
std::swap( edge.source, edge.target );
edge.data.forward = i->isBackward();
edge.data.backward = i->isForward();
edge.data.edgeBasedNodeID = edges.size();
edge.data.forward = input_edge.isBackward();
edge.data.backward = input_edge.isForward();
edge.data.reversedEdge = true;
edges.push_back( edge );
edge_list.push_back( edge );
}
}
std::vector<NodeBasedEdge>().swap(inputEdges);
std::sort( edges.begin(), edges.end() );
_nodeBasedGraph = boost::make_shared<TarjanDynamicGraph>( nodes, edges );
std::vector<NodeBasedEdge>().swap(input_edges);
BOOST_ASSERT_MSG(
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() {
@ -211,162 +220,203 @@ public:
DeleteFileIfExists("component.shx");
DeleteFileIfExists("component.shp");
Percent p(_nodeBasedGraph->GetNumberOfNodes());
const char *pszDriverName = "ESRI Shapefile";
OGRSFDriver *poDriver;
Percent p(m_node_based_graph->GetNumberOfNodes());
OGRRegisterAll();
poDriver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(
pszDriverName );
if( poDriver == NULL )
{
printf( "%s driver not available.\n", pszDriverName );
exit( 1 );
const char *pszDriverName = "ESRI Shapefile";
OGRSFDriver * poDriver = OGRSFDriverRegistrar::GetRegistrar()->
GetDriverByName( pszDriverName );
if( NULL == poDriver ) {
throw OSRMException("ESRI Shapefile driver not available");
}
OGRDataSource *poDS;
poDS = poDriver->CreateDataSource( "component.shp", 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
OGRDataSource * poDS = poDriver->CreateDataSource(
"component.shp",
NULL
);
if(_nodeBasedGraph->GetEdgeData(e1).type != SHRT_MAX) {
assert(e1 != UINT_MAX);
assert(u != UINT_MAX);
assert(v != UINT_MAX);
if( NULL == poDS ) {
throw OSRMException("Creation of output file failed");
}
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
if(std::min(vectorOfComponentSizes[componentsIndex[u]], vectorOfComponentSizes[componentsIndex[v]]) < 10) {
//INFO("(" << inputNodeInfoList[u].lat/COORDINATE_PRECISION << ";" << inputNodeInfoList[u].lon/COORDINATE_PRECISION << ") -> (" << inputNodeInfoList[v].lat/COORDINATE_PRECISION << ";" << inputNodeInfoList[v].lon/COORDINATE_PRECISION << ")");
if(size_of_containing_component < 10) {
OGRLineString lineString;
lineString.addPoint(inputNodeInfoList[u].lon/COORDINATE_PRECISION, inputNodeInfoList[u].lat/COORDINATE_PRECISION);
lineString.addPoint(inputNodeInfoList[v].lon/COORDINATE_PRECISION, inputNodeInfoList[v].lat/COORDINATE_PRECISION);
OGRFeature *poFeature;
poFeature = OGRFeature::CreateFeature( poLayer->GetLayerDefn() );
lineString.addPoint(
m_coordinate_list[u].lon/COORDINATE_PRECISION,
m_coordinate_list[u].lat/COORDINATE_PRECISION
);
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 );
if( poLayer->CreateFeature( poFeature ) != OGRERR_NONE ) {
if( OGRERR_NONE != poLayer->CreateFeature(poFeature) ) {
throw OSRMException(
"Failed to create feature in shapefile."
);
@ -377,39 +427,66 @@ public:
}
}
OGRDataSource::DestroyDataSource( poDS );
std::vector<NodeID>().swap(vectorOfComponentSizes);
std::vector<NodeID>().swap(componentsIndex);
SimpleLogger().Write() << "total network distance: " << (uint64_t)total_network_distance/100/1000. << " km";
std::vector<NodeID>().swap(component_size_vector);
BOOST_ASSERT_MSG(
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:
unsigned CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const {
std::pair < NodeID, NodeID > restrictionSource = std::make_pair(u, v);
RestrictionMap::const_iterator restrIter = _restrictionMap.find(restrictionSource);
if (restrIter != _restrictionMap.end()) {
unsigned index = restrIter->second;
BOOST_FOREACH(RestrictionSource restrictionTarget, _restrictionBucketVector.at(index)) {
if(restrictionTarget.second) {
return restrictionTarget.first;
std::pair < NodeID, NodeID > restriction_source = std::make_pair(u, v);
RestrictionMap::const_iterator restriction_iterator = m_restriction_map.find(restriction_source);
if (restriction_iterator != m_restriction_map.end()) {
const unsigned index = restriction_iterator->second;
BOOST_FOREACH(
const RestrictionSource & restriction_target,
m_restriction_bucket_list.at(index)
) {
if(restriction_target.second) {
return restriction_target.first;
}
}
}
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.
std::pair < NodeID, NodeID > restrictionSource = std::make_pair(u, v);
RestrictionMap::const_iterator restrIter = _restrictionMap.find(restrictionSource);
if (restrIter != _restrictionMap.end()) {
unsigned index = restrIter->second;
BOOST_FOREACH(RestrictionTarget restrictionTarget, _restrictionBucketVector.at(index)) {
if(w == restrictionTarget.first)
std::pair < NodeID, NodeID > restriction_source = std::make_pair(u, v);
RestrictionMap::const_iterator restriction_iterator = m_restriction_map.find(restriction_source);
if (restriction_iterator != m_restriction_map.end()) {
const unsigned index = restriction_iterator->second;
BOOST_FOREACH(
const restriction_target & restriction_target,
m_restriction_bucket_list.at(index)
) {
if(w == restriction_target.first) {
return true;
}
}
}
return false;
}
void DeleteFileIfExists(const std::string file_name) const {
void DeleteFileIfExists(const std::string & file_name) const {
if (boost::filesystem::exists(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)
project(OSRM)
include(FindPackageHandleStandardArgs)
set(HUGO "${CMAKE_CURRENT_SOURCE_DIR}")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
include(GetGitRevisionDescription)
@ -19,8 +20,8 @@ endif(IS_64_SYSTEM)
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
COMMAND ${CMAKE_COMMAND} -P
${CMAKE_SOURCE_DIR}/cmake/UUID-Config.cmake
COMMAND ${CMAKE_COMMAND} -DSOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}
-P ${CMAKE_SOURCE_DIR}/cmake/UUID-Config.cmake
DEPENDS
${CMAKE_SOURCE_DIR}/Util/UUID.cpp.in
${CMAKE_SOURCE_DIR}/cmake/UUID-Config.cmake

View File

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

View File

@ -18,9 +18,7 @@
or see http://www.gnu.org/licenses/agpl.txt.
*/
/*
* This class constructs the edge base representation of a graph from a given node based edge list
*/
// This class constructs the edge-expanded routing graph
#ifndef EDGEBASEDGRAPHFACTORY_H_
#define EDGEBASEDGRAPHFACTORY_H_
@ -31,15 +29,12 @@
#include "../Extractor/ExtractorStructs.h"
#include "../DataStructures/HashTable.h"
#include "../DataStructures/ImportEdge.h"
#include "../DataStructures/MercatorUtil.h"
#include "../DataStructures/QueryEdge.h"
#include "../DataStructures/Percent.h"
#include "../DataStructures/TurnInstructions.h"
#include "../Util/LuaUtil.h"
#include "../Util/SimpleLogger.h"
#include <stxxl.h>
#include <boost/foreach.hpp>
#include <boost/make_shared.hpp>
#include <boost/noncopyable.hpp>
@ -47,9 +42,8 @@
#include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp>
#include <cstdlib>
#include <algorithm>
#include <fstream>
#include <queue>
#include <vector>
@ -67,6 +61,7 @@ public:
weight(UINT_MAX >> 1),
ignoreInGrid(false)
{ }
bool operator<(const EdgeBasedNode & other) const {
return other.id < id;
}
@ -100,33 +95,47 @@ public:
};
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 uTurnPenalty;
bool has_turn_penalty_function;
} speedProfile;
} speed_profile;
explicit EdgeBasedGraphFactory(
int nodes,
std::vector<ImportEdge> & inputEdges,
std::vector<NodeID> & _bollardNodes,
std::vector<NodeID> & trafficLights,
std::vector<TurnRestriction> & inputRestrictions,
std::vector<NodeInfo> & nI,
SpeedProfileProperties speedProfile
int number_of_nodes,
std::vector<ImportEdge> & input_edge_list,
std::vector<NodeID> & barrier_node_list,
std::vector<NodeID> & traffic_light_node_list,
std::vector<TurnRestriction> & input_restrictions_list,
std::vector<NodeInfo> & m_node_info_list,
SpeedProfileProperties speed_profile
);
void Run(const char * originalEdgeDataFilename, lua_State *myLuaState);
void GetEdgeBasedEdges( DeallocatingVector< EdgeBasedEdge >& edges );
void GetEdgeBasedNodes( std::vector< EdgeBasedNode> & nodes);
void GetOriginalEdgeData( std::vector< OriginalEdgeData> & originalEdgeData);
TurnInstruction AnalyzeTurn(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;
void GetOriginalEdgeData( std::vector<OriginalEdgeData> & originalEdgeData);
TurnInstruction AnalyzeTurn(
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;
private:
struct _NodeBasedEdgeData {
struct NodeBasedEdgeData {
int distance;
unsigned edgeBasedNodeID;
unsigned nameID;
@ -151,35 +160,44 @@ private:
unsigned m_turn_restrictions_count;
typedef DynamicGraph< _NodeBasedEdgeData > _NodeBasedDynamicGraph;
typedef _NodeBasedDynamicGraph::InputEdge _NodeBasedEdge;
std::vector<NodeInfo> inputNodeInfoList;
unsigned numberOfTurnRestrictions;
boost::shared_ptr<_NodeBasedDynamicGraph> _nodeBasedGraph;
boost::unordered_set<NodeID> _barrierNodes;
boost::unordered_set<NodeID> _trafficLights;
typedef DynamicGraph<NodeBasedEdgeData> NodeBasedDynamicGraph;
typedef NodeBasedDynamicGraph::InputEdge NodeBasedEdge;
typedef NodeBasedDynamicGraph::NodeIterator NodeIterator;
typedef NodeBasedDynamicGraph::EdgeIterator EdgeIterator;
typedef NodeBasedDynamicGraph::EdgeData EdgeData;
typedef std::pair<NodeID, NodeID> RestrictionSource;
typedef std::pair<NodeID, bool> RestrictionTarget;
typedef std::vector<RestrictionTarget> EmanatingRestrictionsVector;
typedef boost::unordered_map<RestrictionSource, unsigned > RestrictionMap;
std::vector<EmanatingRestrictionsVector> _restrictionBucketVector;
RestrictionMap _restrictionMap;
DeallocatingVector<EdgeBasedEdge> edgeBasedEdges;
std::vector<EdgeBasedNode> edgeBasedNodes;
std::vector<NodeInfo> m_node_info_list;
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(
_NodeBasedDynamicGraph::EdgeIterator e1,
_NodeBasedDynamicGraph::NodeIterator u,
_NodeBasedDynamicGraph::NodeIterator v,
NodeBasedDynamicGraph::EdgeIterator e1,
NodeBasedDynamicGraph::NodeIterator u,
NodeBasedDynamicGraph::NodeIterator v,
bool belongsToTinyComponent);
template<class CoordinateT>
double GetAngleBetweenTwoEdges(const CoordinateT& A, const CoordinateT& C, const CoordinateT& B) const;
};
#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.
*/
#ifndef CONCURRENTQUEUE_H_INCLUDED
#define CONCURRENTQUEUE_H_INCLUDED
#ifndef CONCURRENTQUEUE_H_
#define CONCURRENTQUEUE_H_
#include "../typedefs.h"
#include <boost/bind.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/thread.hpp>
#include "../typedefs.h"
template<typename Data>
class ConcurrentQueue {
typedef typename boost::circular_buffer<Data>::size_type size_t;
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);
m_not_full.wait(lock, boost::bind(&ConcurrentQueue<Data>::is_not_full, this));
internal_queue.push_back(data);
m_not_full.wait(
lock,
boost::bind(&ConcurrentQueue<Data>::is_not_full, this)
);
m_internal_queue.push_back(data);
lock.unlock();
m_not_empty.notify_one();
}
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);
m_not_empty.wait(lock, boost::bind(&ConcurrentQueue<Data>::is_not_empty, this));
popped_value=internal_queue.front();
internal_queue.pop_front();
m_not_empty.wait(
lock,
boost::bind(&ConcurrentQueue<Data>::is_not_empty, this)
);
popped_value = m_internal_queue.front();
m_internal_queue.pop_front();
lock.unlock();
m_not_full.notify_one();
}
inline bool try_pop(Data& popped_value) {
boost::mutex::scoped_lock lock(m_mutex);
if(internal_queue.empty()) {
if(m_internal_queue.empty()) {
return false;
}
popped_value=internal_queue.front();
internal_queue.pop_front();
popped_value=m_internal_queue.front();
m_internal_queue.pop_front();
lock.unlock();
m_not_full.notify_one();
return true;
}
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::condition m_not_empty;
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_
#define FIXED_POINT_COORDINATE_H_
#include "../DataStructures/MercatorUtil.h"
#include "../Util/StringUtil.h"
#include <cassert>
@ -35,7 +36,7 @@ struct FixedPointCoordinate {
int lat;
int lon;
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() {
lat = INT_MIN;
@ -141,4 +142,22 @@ static inline void convertInternalReversedCoordinateToString(const FixedPointCoo
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_ */

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.
*/
#ifndef EDGE_H
#define EDGE_H
#ifndef IMPORT_EDGE_H
#define IMPORT_EDGE_H
#include "../Util/OSRMException.h"
#include <cassert>
#include "../typedefs.h"
#include <boost/assert.hpp>
class NodeBasedEdge {
public:
public:
bool operator< (const NodeBasedEdge& e) const {
if (source() == e.source()) {
if (target() == e.target()) {
@ -58,9 +59,9 @@ public:
_target(t),
_name(n),
_weight(w),
_type(ty),
forward(f),
backward(b),
_type(ty),
_roundabout(ra),
_ignoreInGrid(ig),
_accessRestricted(ar),
@ -75,8 +76,9 @@ public:
NodeID source() const {return _source; }
NodeID name() const { return _name; }
EdgeWeight weight() const {return _weight; }
short type() const { assert(_type >= 0); return _type; }
short type() const {
BOOST_ASSERT_MSG(_type >= 0, "type of ImportEdge invalid");
return _type; }
bool isBackward() const { return backward; }
bool isForward() const { return forward; }
bool isLocatable() const { return _type != 14; }
@ -85,28 +87,26 @@ public:
bool isAccessRestricted() const { return _accessRestricted; }
bool isContraFlow() const { return _contraFlow; }
//TODO: names need to be fixed.
NodeID _source;
NodeID _target;
NodeID _name;
EdgeWeight _weight;
bool forward;
bool backward;
short _type;
bool _roundabout;
bool _ignoreInGrid;
bool _accessRestricted;
bool _contraFlow;
bool forward:1;
bool backward:1;
bool _roundabout:1;
bool _ignoreInGrid:1;
bool _accessRestricted:1;
bool _contraFlow:1;
private:
/** Default constructor. target and weight are set to 0.*/
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.
NodeBasedEdge() { }
};
class EdgeBasedEdge {
public:
public:
bool operator< (const EdgeBasedEdge& e) const {
if (source() == e.source()) {
if (target() == e.target()) {
@ -141,7 +141,14 @@ public:
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_target(t),
m_edgeID(v),
@ -150,12 +157,13 @@ public:
m_backward(b)
{}
NodeID target() const {return m_target; }
NodeID source() const {return m_source; }
EdgeWeight weight() const {return m_weight; }
NodeID target() const { return m_target; }
NodeID source() const { return m_source; }
EdgeWeight weight() const { return m_weight; }
NodeID id() const { return m_edgeID; }
bool isBackward() const { return m_backward; }
bool isForward() const { return m_forward; }
private:
NodeID m_source;
NodeID m_target;
@ -167,4 +175,4 @@ private:
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;
class NodeInformationHelpDesk : boost::noncopyable {
public:
NodeInformationHelpDesk(
const std::string & ramIndexInput,
const std::string & fileIndexInput,
const std::string & ram_index_filename,
const std::string & mem_index_filename,
const std::string & nodes_filename,
const std::string & edges_filename,
const unsigned number_of_nodes,
const unsigned check_sum
) : number_of_nodes(number_of_nodes), check_sum(check_sum)
const unsigned m_number_of_nodes,
const unsigned m_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");
}
if ( fileIndexInput.empty() ) {
if ( mem_index_filename.empty() ) {
throw OSRMException("no mem index file name in server ini");
}
if ( nodes_filename.empty() ) {
@ -63,47 +66,37 @@ public:
throw OSRMException("no edges file name in server ini");
}
read_only_rtree = new StaticRTree<RTreeLeaf>(
ramIndexInput,
fileIndexInput
m_ro_rtree_ptr = new StaticRTree<RTreeLeaf>(
ram_index_filename,
mem_index_filename
);
BOOST_ASSERT_MSG(
0 == coordinateVector.size(),
0 == m_coordinate_list.size(),
"Coordinate vector not empty"
);
LoadNodesAndEdges(nodes_filename, edges_filename);
}
//Todo: Shared memory mechanism
~NodeInformationHelpDesk() {
delete read_only_rtree;
delete m_ro_rtree_ptr;
}
inline int getLatitudeOfNode(const unsigned id) const {
const NodeID node = origEdgeData_viaNode.at(id);
return coordinateVector.at(node).lat;
inline FixedPointCoordinate GetCoordinateOfNode(const unsigned id) const {
const NodeID node = m_via_node_list.at(id);
return m_coordinate_list.at(node);
}
inline int getLongitudeOfNode(const unsigned id) const {
const NodeID node = origEdgeData_viaNode.at(id);
return coordinateVector.at(node).lon;
inline unsigned GetNameIndexFromEdgeID(const unsigned id) const {
return m_name_ID_list.at(id);
}
inline unsigned getNameIndexFromEdgeID(const unsigned id) const {
return origEdgeData_nameID.at(id);
inline TurnInstruction GetTurnInstructionForEdgeID(const unsigned id) const {
return m_turn_instruction_list.at(id);
}
inline TurnInstruction getTurnInstructionFromEdgeID(const unsigned id) const {
return origEdgeData_turnInstruction.at(id);
}
inline NodeID getNumberOfNodes() const {
return number_of_nodes;
}
inline NodeID getNumberOfNodes2() const {
return coordinateVector.size();
inline NodeID GetNumberOfNodes() const {
return m_number_of_nodes;
}
inline bool FindNearestNodeCoordForLatLon(
@ -112,12 +105,12 @@ public:
const unsigned zoom_level = 18
) const {
PhantomNode resulting_phantom_node;
bool foundNode = FindPhantomNodeForCoordinate(
bool found_node = FindPhantomNodeForCoordinate(
input_coordinate,
resulting_phantom_node, zoom_level
);
result = resulting_phantom_node.location;
return foundNode;
return found_node;
}
inline bool FindPhantomNodeForCoordinate(
@ -125,7 +118,7 @@ public:
PhantomNode & resulting_phantom_node,
const unsigned zoom_level
) const {
return read_only_rtree->FindPhantomNodeForCoordinate(
return m_ro_rtree_ptr->FindPhantomNodeForCoordinate(
input_coordinate,
resulting_phantom_node,
zoom_level
@ -133,7 +126,7 @@ public:
}
inline unsigned GetCheckSum() const {
return check_sum;
return m_check_sum;
}
private:
@ -157,48 +150,63 @@ private:
throw OSRMException("edges file is empty");
}
boost::filesystem::ifstream nodes_input_stream(nodes_file, std::ios::binary);
boost::filesystem::ifstream edges_input_stream(edges_file, std::ios::binary);
boost::filesystem::ifstream nodes_input_stream(
nodes_file,
std::ios::binary
);
SimpleLogger().Write(logDEBUG) << "Loading node data";
NodeInfo b;
boost::filesystem::ifstream edges_input_stream(
edges_file, std::ios::binary
);
SimpleLogger().Write(logDEBUG)
<< "Loading node data";
NodeInfo current_node;
while(!nodes_input_stream.eof()) {
nodes_input_stream.read((char *)&b, sizeof(NodeInfo));
coordinateVector.push_back(FixedPointCoordinate(b.lat, b.lon));
nodes_input_stream.read((char *)&current_node, sizeof(NodeInfo));
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();
SimpleLogger().Write(logDEBUG) << "Loading edge data";
unsigned numberOfOrigEdges(0);
edges_input_stream.read((char*)&numberOfOrigEdges, sizeof(unsigned));
origEdgeData_viaNode.resize(numberOfOrigEdges);
origEdgeData_nameID.resize(numberOfOrigEdges);
origEdgeData_turnInstruction.resize(numberOfOrigEdges);
SimpleLogger().Write(logDEBUG)
<< "Loading edge data";
unsigned number_of_edges = 0;
edges_input_stream.read((char*)&number_of_edges, sizeof(unsigned));
m_via_node_list.resize(number_of_edges);
m_name_ID_list.resize(number_of_edges);
m_turn_instruction_list.resize(number_of_edges);
OriginalEdgeData deserialized_originalEdgeData;
for(unsigned i = 0; i < numberOfOrigEdges; ++i) {
OriginalEdgeData current_edge_data;
for(unsigned i = 0; i < number_of_edges; ++i) {
edges_input_stream.read(
(char*)&(deserialized_originalEdgeData),
(char*)&(current_edge_data),
sizeof(OriginalEdgeData)
);
origEdgeData_viaNode[i] = deserialized_originalEdgeData.viaNode;
origEdgeData_nameID[i] = deserialized_originalEdgeData.nameID;
origEdgeData_turnInstruction[i] = deserialized_originalEdgeData.turnInstruction;
m_via_node_list[i] = current_edge_data.viaNode;
m_name_ID_list[i] = current_edge_data.nameID;
m_turn_instruction_list[i] = current_edge_data.turnInstruction;
}
edges_input_stream.close();
SimpleLogger().Write(logDEBUG) << "Loaded " << numberOfOrigEdges << " orig edges";
SimpleLogger().Write(logDEBUG) << "Opening NN indices";
SimpleLogger().Write(logDEBUG)
<< "Loaded " << number_of_edges << " orig edges";
SimpleLogger().Write(logDEBUG)
<< "Opening NN indices";
}
std::vector<FixedPointCoordinate> coordinateVector;
std::vector<NodeID> origEdgeData_viaNode;
std::vector<unsigned> origEdgeData_nameID;
std::vector<TurnInstruction> origEdgeData_turnInstruction;
std::vector<FixedPointCoordinate> m_coordinate_list;
std::vector<NodeID> m_via_node_list;
std::vector<unsigned> m_name_ID_list;
std::vector<TurnInstruction> m_turn_instruction_list;
StaticRTree<EdgeBasedGraphFactory::EdgeBasedNode> * read_only_rtree;
const unsigned number_of_nodes;
const unsigned check_sum;
StaticRTree<EdgeBasedGraphFactory::EdgeBasedNode> * m_ro_rtree_ptr;
const unsigned m_number_of_nodes;
const unsigned m_check_sum;
};
#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.
*/
#ifndef QUERYEDGE_H_
#define QUERYEDGE_H_

View File

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

View File

@ -24,26 +24,26 @@ SearchEngine::SearchEngine(
QueryGraph * g,
NodeInformationHelpDesk * nh,
std::vector<std::string> & n
) :
) :
_queryData(g, nh, n),
shortestPath(_queryData),
alternativePaths(_queryData)
{}
SearchEngine::~SearchEngine() {}
{}
SearchEngine::~SearchEngine() {}
void SearchEngine::GetCoordinatesForNodeID(
NodeID id,
FixedPointCoordinate& result
) const {
result.lat = _queryData.nodeHelpDesk->getLatitudeOfNode(id);
result.lon = _queryData.nodeHelpDesk->getLongitudeOfNode(id);
) const {
result = _queryData.nodeHelpDesk->GetCoordinateOfNode(id);
}
void SearchEngine::FindPhantomNodeForCoordinate(
const FixedPointCoordinate & location,
PhantomNode & result,
const unsigned zoomLevel
) const {
) const {
_queryData.nodeHelpDesk->FindPhantomNodeForCoordinate(
location,
result, zoomLevel
@ -53,17 +53,20 @@ void SearchEngine::FindPhantomNodeForCoordinate(
NodeID SearchEngine::GetNameIDForOriginDestinationNodeID(
const NodeID s,
const NodeID t
) const {
if(s == t){
) const {
if(s == t) {
return 0;
}
EdgeID e = _queryData.graph->FindEdge(s, t);
if(e == UINT_MAX) {
e = _queryData.graph->FindEdge( t, s );
}
if(UINT_MAX == e) {
return 0;
}
assert(e != UINT_MAX);
const QueryEdge::EdgeData ed = _queryData.graph->GetEdgeData(e);
return ed.id;
@ -86,4 +89,3 @@ SearchEngineHeapPtr SearchEngineData::backwardHeap2;
SearchEngineHeapPtr SearchEngineData::forwardHeap3;
SearchEngineHeapPtr SearchEngineData::backwardHeap3;

View File

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

View File

@ -21,6 +21,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef STATICGRAPH_H_INCLUDED
#define STATICGRAPH_H_INCLUDED
#include "../DataStructures/Percent.h"
#include "../Util/SimpleLogger.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/PhantomNodes.h"
#include "../DataStructures/RawRouteData.h"
#include "../DataStructures/SearchEngine.h"
#include "../Plugins/RawRouteData.h"
#include "../Server/BasicDatastructures.h"
#include "../Util/StringUtil.h"
#include "../typedefs.h"

View File

@ -72,13 +72,10 @@ void BaseParser::ParseNodeInLua(ImportNode& n, 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) );
}
bool BaseParser::ShouldIgnoreRestriction(const std::string& except_tag_string) const {
bool BaseParser::ShouldIgnoreRestriction(const std::string & except_tag_string) const {
//should this restriction be ignored? yes if there's an overlap between:
//a) the list of modes in the except tag of the restriction (except_tag_string), ex: except=bus;bicycle
//b) the lua profile defines a hierachy of modes, ex: [access, vehicle, bicycle]

View File

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

View File

@ -154,7 +154,7 @@ struct CmpWayByID : public std::binary_function<_WayIDStartAndEndEdge, _WayIDSta
struct Cmp : public std::binary_function<NodeID, NodeID, bool> {
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;
}
value_type max_value() {

View File

@ -173,14 +173,14 @@ inline void PBFParser::parseDenseNode(_ThreadData * threadData) {
extracted_nodes_vector[i].lon = COORDINATE_PRECISION*( ( double ) m_lastDenseLongitude * threadData->PBFprimitiveBlock.granularity() + threadData->PBFprimitiveBlock.lon_offset() ) / NANO;
while (denseTagIndex < dense.keys_vals_size()) {
const int tagValue = dense.keys_vals( denseTagIndex );
if( 0==tagValue ) {
if( 0 == tagValue ) {
++denseTagIndex;
break;
}
const int keyValue = dense.keys_vals ( denseTagIndex+1 );
const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(tagValue).data();
const std::string & value = threadData->PBFprimitiveBlock.stringtable().s(keyValue).data();
extracted_nodes_vector[i].keyVals.insert(std::make_pair(key, value));
const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(tagValue);
const std::string & value = threadData->PBFprimitiveBlock.stringtable().s(keyValue);
extracted_nodes_vector[i].keyVals.emplace(key, value);
denseTagIndex += 2;
}
}
@ -191,7 +191,7 @@ inline void PBFParser::parseDenseNode(_ThreadData * threadData) {
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);
}
}
@ -209,7 +209,8 @@ inline void PBFParser::parseRelation(_ThreadData * threadData) {
return;
}
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;
const OSMPBF::Relation& inputRelation = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).relations(i);
bool isRestriction = false;
@ -241,8 +242,12 @@ inline void PBFParser::parseRelation(_ThreadData * threadData) {
if(isRestriction) {
int64_t lastRef = 0;
_RawRestrictionContainer currentRestrictionContainer(isOnlyRestriction);
for(int rolesIndex = 0; rolesIndex < inputRelation.roles_sid_size(); ++rolesIndex) {
std::string role(threadData->PBFprimitiveBlock.stringtable().s( inputRelation.roles_sid( rolesIndex ) ).data());
for(
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);
if(!("from" == role || "to" == role || "via" == role)) {
@ -280,7 +285,6 @@ inline void PBFParser::parseRelation(_ThreadData * threadData) {
break;
default: //should not happen
//cout << "unknown";
assert(false);
break;
}
@ -309,17 +313,23 @@ inline void PBFParser::parseWay(_ThreadData * threadData) {
for(int j = 0; j < number_of_keys; ++j) {
const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(inputWay.keys(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 )
for(int i = 0; i < number_of_ways; ++i) {
ExtractionWay & w = parsed_way_vector[i];
ParseWayInLua( w, scriptingEnvironment.getLuaStateForThreadID(omp_get_thread_num()) );
if(2 > w.path.size()) {
continue;
}
ParseWayInLua( w, scriptingEnvironment.getLuaStateForThreadID( omp_get_thread_num()) );
}
BOOST_FOREACH(ExtractionWay & w, parsed_way_vector) {
if(2 > w.path.size()) {
continue;
}
extractor_callbacks->wayFunction(w);
}
}
@ -330,21 +340,21 @@ inline void PBFParser::loadGroup(_ThreadData * threadData) {
#endif
const OSMPBF::PrimitiveGroup& group = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID );
threadData->entityTypeIndicator = 0;
if ( group.nodes_size() != 0 ) {
threadData->entityTypeIndicator = TypeDummy;
if ( 0 != group.nodes_size() ) {
threadData->entityTypeIndicator = TypeNode;
}
if ( group.ways_size() != 0 ) {
if ( 0 != group.ways_size() ) {
threadData->entityTypeIndicator = TypeWay;
}
if ( group.relations_size() != 0 ) {
if ( 0 != group.relations_size() ) {
threadData->entityTypeIndicator = TypeRelation;
}
if ( group.has_dense() ) {
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) {

View File

@ -44,16 +44,17 @@
class PBFParser : public BaseParser {
enum EntityType {
TypeDummy = 0,
TypeNode = 1,
TypeWay = 2,
TypeRelation = 4,
TypeDenseNode = 8
} ;
};
struct _ThreadData {
int currentGroupID;
int currentEntityID;
short entityTypeIndicator;
EntityType entityTypeIndicator;
OSMPBF::BlobHeader PBFBlobHeader;
OSMPBF::Blob PBFBlob;
@ -74,18 +75,18 @@ public:
private:
inline void ReadData();
inline void ParseData();
inline void parseDenseNode(_ThreadData * threadData);
inline void parseNode(_ThreadData * );
inline void parseRelation(_ThreadData * threadData);
inline void parseWay(_ThreadData * threadData);
inline void parseDenseNode (_ThreadData * threadData);
inline void parseNode (_ThreadData * threadData);
inline void parseRelation (_ThreadData * threadData);
inline void parseWay (_ThreadData * threadData);
inline void loadGroup(_ThreadData * threadData);
inline void loadBlock(_ThreadData * threadData);
inline bool readPBFBlobHeader(std::fstream& stream, _ThreadData * threadData);
inline bool unpackZLIB(std::fstream &, _ThreadData * threadData);
inline bool unpackLZMA(std::fstream &, _ThreadData * );
inline bool readBlob(std::fstream& stream, _ThreadData * threadData) ;
inline bool readNextBlock(std::fstream& stream, _ThreadData * threadData);
inline void loadGroup (_ThreadData * threadData);
inline void loadBlock (_ThreadData * threadData);
inline bool readPBFBlobHeader(std::fstream & stream, _ThreadData * threadData);
inline bool unpackZLIB (std::fstream & stream, _ThreadData * threadData);
inline bool unpackLZMA (std::fstream & stream, _ThreadData * threadData);
inline bool readBlob (std::fstream & stream, _ThreadData * threadData);
inline bool readNextBlock (std::fstream & stream, _ThreadData * threadData);
static const int NANO = 1000 * 1000 * 1000;
static const int MAX_BLOB_HEADER_SIZE = 64 * 1024;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -23,7 +23,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef BASICROUTINGINTERFACE_H_
#define BASICROUTINGINTERFACE_H_
#include "../Plugins/RawRouteData.h"
#include "../DataStructures/RawRouteData.h"
#include "../Util/ContainerUtils.h"
#include "../Util/SimpleLogger.h"
@ -148,7 +148,14 @@ public:
recursionStack.push(std::make_pair(edge.first, middle));
} else {
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
#define ROUTE_PARAMETERS_H
#include "../DataStructures/Coordinate.h"
#include "../DataStructures/HashTable.h"
#include "../../DataStructures/Coordinate.h"
#include "../../DataStructures/HashTable.h"
#include <boost/fusion/container/vector.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 "BasicDatastructures.h"
#include "DataStructures/RouteParameters.h"
#include "../Library/OSRM.h"
#include "../Plugins/RouteParameters.h"
#include "../Util/SimpleLogger.h"
#include "../Util/StringUtil.h"
#include "../typedefs.h"
@ -47,25 +47,35 @@ public:
try {
std::string request(req.uri);
{ //This block logs the current request to std out. should be moved to a logging component
time_t ltime;
struct tm *Tm;
ltime=time(NULL);
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 << " " <<
req.endpoint.to_string() << " " << req.referrer << ( 0 == req.referrer.length() ? "- " :" ") << req.agent << ( 0 == req.agent.length() ? "- " :" ") << req.uri;
}
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 << " " << req.endpoint.to_string() << " " <<
req.referrer << ( 0 == req.referrer.length() ? "- " :" ") <<
req.agent << ( 0 == req.agent.length() ? "- " :" ") << req.uri;
RouteParameters routeParameters;
APIGrammarParser apiParser(&routeParameters);
std::string::iterator it = request.begin();
bool result = boost::spirit::qi::parse(it, request.end(), apiParser);
if (!result || (it != request.end()) ) {
const bool result = boost::spirit::qi::parse(
it,
request.end(),
apiParser
);
if ( !result || (it != request.end()) ) {
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;
intToString(position, tmp_position_string);
rep.content += "Input seems to be malformed close to position ";
@ -73,7 +83,7 @@ public:
rep.content += request;
rep.content += tmp_position_string;
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) {
rep.content += "&nbsp;";
}

View File

@ -30,6 +30,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "../Util/InputFileUtil.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../Util/UUID.h"
#include <boost/foreach.hpp>
#include <fstream>
@ -58,6 +59,16 @@ int main (int argc, char * argv[]) {
SimpleLogger().Write() <<
"Using restrictions from file: " << argv[2];
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()) {
throw OSRMException("Could not access <osrm-restrictions> files");
}
@ -92,6 +103,11 @@ int main (int argc, char * argv[]) {
);
input_stream.close();
BOOST_ASSERT_MSG(
restrictions_vector.size() == usable_restriction_count,
"size of restrictions_vector changed"
);
SimpleLogger().Write() <<
restrictions_vector.size() << " restrictions, " <<
bollard_node_IDs_vector.size() << " bollard nodes, " <<

View File

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

View File

@ -1,12 +1,11 @@
set(oldfile ${CMAKE_SOURCE_DIR}/../Util/UUID.cpp)
if (EXISTS ${oldfile})
file(REMOVE_RECURSE ${oldfile})
set(OLDFILE ${SOURCE_DIR}/Util/UUID.cpp)
if (EXISTS ${OLDFILE})
file(REMOVE_RECURSE ${OLDFILE})
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)
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 )
CONFIGURE_FILE( ${SOURCE_DIR}/Util/UUID.cpp.in ${SOURCE_DIR}/Util/UUID.cpp )

View File

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