Merge branch 'develop' into experimental/program_options
This commit is contained in:
commit
9d23dee3fc
@ -35,11 +35,13 @@ Strongly connected components using Tarjan's Algorithm
|
|||||||
|
|
||||||
#include "../Util/SimpleLogger.h"
|
#include "../Util/SimpleLogger.h"
|
||||||
|
|
||||||
|
#include <boost/assert.hpp>
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
#include <boost/integer.hpp>
|
#include <boost/integer.hpp>
|
||||||
#include <boost/make_shared.hpp>
|
#include <boost/make_shared.hpp>
|
||||||
#include <boost/unordered_map.hpp>
|
#include <boost/unordered_map.hpp>
|
||||||
|
#include <boost/unordered_set.hpp>
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#include <gdal.h>
|
#include <gdal.h>
|
||||||
@ -48,7 +50,7 @@ Strongly connected components using Tarjan's Algorithm
|
|||||||
#include <gdal/gdal.h>
|
#include <gdal/gdal.h>
|
||||||
#include <gdal/ogrsf_frmts.h>
|
#include <gdal/ogrsf_frmts.h>
|
||||||
#endif
|
#endif
|
||||||
#include <cassert>
|
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -64,7 +66,6 @@ private:
|
|||||||
|
|
||||||
struct TarjanEdgeData {
|
struct TarjanEdgeData {
|
||||||
int distance;
|
int distance;
|
||||||
unsigned edgeBasedNodeID;
|
|
||||||
unsigned nameID:31;
|
unsigned nameID:31;
|
||||||
bool shortcut:1;
|
bool shortcut:1;
|
||||||
short type;
|
short type;
|
||||||
@ -77,7 +78,10 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct TarjanStackFrame {
|
struct TarjanStackFrame {
|
||||||
explicit TarjanStackFrame(NodeID _v, NodeID p) : v(_v), parent(p) {}
|
explicit TarjanStackFrame(
|
||||||
|
NodeID v,
|
||||||
|
NodeID parent
|
||||||
|
) : v(v), parent(parent) { }
|
||||||
NodeID v;
|
NodeID v;
|
||||||
NodeID parent;
|
NodeID parent;
|
||||||
};
|
};
|
||||||
@ -85,18 +89,17 @@ private:
|
|||||||
typedef DynamicGraph<TarjanEdgeData> TarjanDynamicGraph;
|
typedef DynamicGraph<TarjanEdgeData> TarjanDynamicGraph;
|
||||||
typedef TarjanDynamicGraph::InputEdge TarjanEdge;
|
typedef TarjanDynamicGraph::InputEdge TarjanEdge;
|
||||||
typedef std::pair<NodeID, NodeID> RestrictionSource;
|
typedef std::pair<NodeID, NodeID> RestrictionSource;
|
||||||
typedef std::pair<NodeID, bool> RestrictionTarget;
|
typedef std::pair<NodeID, bool> restriction_target;
|
||||||
typedef std::vector<RestrictionTarget> EmanatingRestrictionsVector;
|
typedef std::vector<restriction_target> EmanatingRestrictionsVector;
|
||||||
typedef boost::unordered_map<RestrictionSource, unsigned > RestrictionMap;
|
typedef boost::unordered_map<RestrictionSource, unsigned > RestrictionMap;
|
||||||
|
|
||||||
std::vector<NodeInfo> inputNodeInfoList;
|
std::vector<NodeInfo> m_coordinate_list;
|
||||||
unsigned numberOfTurnRestrictions;
|
std::vector<EmanatingRestrictionsVector> m_restriction_bucket_list;
|
||||||
boost::shared_ptr<TarjanDynamicGraph> _nodeBasedGraph;
|
boost::shared_ptr<TarjanDynamicGraph> m_node_based_graph;
|
||||||
boost::unordered_map<NodeID, bool> _barrierNodes;
|
boost::unordered_set<NodeID> m_barrier_node_list;
|
||||||
boost::unordered_map<NodeID, bool> _trafficLights;
|
boost::unordered_set<NodeID> m_traffic_light_list;
|
||||||
|
unsigned m_restriction_counter;
|
||||||
std::vector<EmanatingRestrictionsVector> _restrictionBucketVector;
|
RestrictionMap m_restriction_map;
|
||||||
RestrictionMap _restrictionMap;
|
|
||||||
|
|
||||||
struct EdgeBasedNode {
|
struct EdgeBasedNode {
|
||||||
bool operator<(const EdgeBasedNode & other) const {
|
bool operator<(const EdgeBasedNode & other) const {
|
||||||
@ -116,93 +119,99 @@ private:
|
|||||||
bool ignoreInGrid:1;
|
bool ignoreInGrid:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
DeallocatingVector<EdgeBasedNode> edgeBasedNodes;
|
|
||||||
public:
|
public:
|
||||||
TarjanSCC(
|
TarjanSCC(
|
||||||
int nodes,
|
int number_of_nodes,
|
||||||
std::vector<NodeBasedEdge> & inputEdges,
|
std::vector<NodeBasedEdge> & input_edges,
|
||||||
std::vector<NodeID> & bn,
|
std::vector<NodeID> & bn,
|
||||||
std::vector<NodeID> & tl,
|
std::vector<NodeID> & tl,
|
||||||
std::vector<TurnRestriction> & irs,
|
std::vector<TurnRestriction> & irs,
|
||||||
std::vector<NodeInfo> & nI
|
std::vector<NodeInfo> & nI
|
||||||
) :
|
) :
|
||||||
inputNodeInfoList(nI),
|
m_coordinate_list(nI),
|
||||||
numberOfTurnRestrictions(irs.size())
|
m_restriction_counter(irs.size())
|
||||||
{
|
{
|
||||||
BOOST_FOREACH(const TurnRestriction & restriction, irs) {
|
BOOST_FOREACH(const TurnRestriction & restriction, irs) {
|
||||||
std::pair<NodeID, NodeID> restrictionSource = std::make_pair(
|
std::pair<NodeID, NodeID> restrictionSource = std::make_pair(
|
||||||
restriction.fromNode, restriction.viaNode
|
restriction.fromNode, restriction.viaNode
|
||||||
);
|
);
|
||||||
unsigned index;
|
unsigned index;
|
||||||
RestrictionMap::iterator restrIter = _restrictionMap.find(restrictionSource);
|
RestrictionMap::iterator restriction_iterator = m_restriction_map.find(restrictionSource);
|
||||||
if(restrIter == _restrictionMap.end()) {
|
if(restriction_iterator == m_restriction_map.end()) {
|
||||||
index = _restrictionBucketVector.size();
|
index = m_restriction_bucket_list.size();
|
||||||
_restrictionBucketVector.resize(index+1);
|
m_restriction_bucket_list.resize(index+1);
|
||||||
_restrictionMap[restrictionSource] = index;
|
m_restriction_map[restrictionSource] = index;
|
||||||
} else {
|
} else {
|
||||||
index = restrIter->second;
|
index = restriction_iterator->second;
|
||||||
//Map already contains an is_only_*-restriction
|
//Map already contains an is_only_*-restriction
|
||||||
if(_restrictionBucketVector.at(index).begin()->second)
|
if(m_restriction_bucket_list.at(index).begin()->second) {
|
||||||
continue;
|
continue;
|
||||||
else if(restriction.flags.isOnly){
|
} else if(restriction.flags.isOnly) {
|
||||||
//We are going to insert an is_only_*-restriction. There can be only one.
|
//We are going to insert an is_only_*-restriction. There can be only one.
|
||||||
_restrictionBucketVector.at(index).clear();
|
m_restriction_bucket_list.at(index).clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_restrictionBucketVector.at(index).push_back(
|
m_restriction_bucket_list.at(index).push_back(
|
||||||
std::make_pair(restriction.toNode, restriction.flags.isOnly)
|
std::make_pair(restriction.toNode, restriction.flags.isOnly)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_FOREACH(NodeID id, bn) {
|
m_barrier_node_list.insert(bn.begin(), bn.end());
|
||||||
_barrierNodes[id] = true;
|
m_traffic_light_list.insert(tl.begin(), tl.end());
|
||||||
}
|
|
||||||
BOOST_FOREACH(NodeID id, tl) {
|
|
||||||
_trafficLights[id] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
DeallocatingVector< TarjanEdge > edges;
|
|
||||||
for ( std::vector< NodeBasedEdge >::const_iterator i = inputEdges.begin(); i != inputEdges.end(); ++i ) {
|
|
||||||
|
|
||||||
|
DeallocatingVector< TarjanEdge > edge_list;
|
||||||
|
BOOST_FOREACH(const NodeBasedEdge & input_edge, input_edges) {
|
||||||
TarjanEdge edge;
|
TarjanEdge edge;
|
||||||
if(!i->isForward()) {
|
if(!input_edge.isForward()) {
|
||||||
edge.source = i->target();
|
edge.source = input_edge.target();
|
||||||
edge.target = i->source();
|
edge.target = input_edge.source();
|
||||||
edge.data.backward = i->isForward();
|
edge.data.backward = input_edge.isForward();
|
||||||
edge.data.forward = i->isBackward();
|
edge.data.forward = input_edge.isBackward();
|
||||||
} else {
|
} else {
|
||||||
edge.source = i->source();
|
edge.source = input_edge.source();
|
||||||
edge.target = i->target();
|
edge.target = input_edge.target();
|
||||||
edge.data.forward = i->isForward();
|
edge.data.forward = input_edge.isForward();
|
||||||
edge.data.backward = i->isBackward();
|
edge.data.backward = input_edge.isBackward();
|
||||||
}
|
}
|
||||||
if(edge.source == edge.target)
|
if(edge.source == edge.target) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
edge.data.distance = (std::max)((int)i->weight(), 1 );
|
edge.data.distance = (std::max)((int)input_edge.weight(), 1 );
|
||||||
assert( edge.data.distance > 0 );
|
BOOST_ASSERT( edge.data.distance > 0 );
|
||||||
edge.data.shortcut = false;
|
edge.data.shortcut = false;
|
||||||
edge.data.roundabout = i->isRoundabout();
|
edge.data.roundabout = input_edge.isRoundabout();
|
||||||
edge.data.ignoreInGrid = i->ignoreInGrid();
|
edge.data.ignoreInGrid = input_edge.ignoreInGrid();
|
||||||
edge.data.nameID = i->name();
|
edge.data.nameID = input_edge.name();
|
||||||
edge.data.type = i->type();
|
edge.data.type = input_edge.type();
|
||||||
edge.data.isAccessRestricted = i->isAccessRestricted();
|
edge.data.isAccessRestricted = input_edge.isAccessRestricted();
|
||||||
edge.data.edgeBasedNodeID = edges.size();
|
|
||||||
edge.data.reversedEdge = false;
|
edge.data.reversedEdge = false;
|
||||||
edges.push_back( edge );
|
edge_list.push_back( edge );
|
||||||
if( edge.data.backward ) {
|
if( edge.data.backward ) {
|
||||||
std::swap( edge.source, edge.target );
|
std::swap( edge.source, edge.target );
|
||||||
edge.data.forward = i->isBackward();
|
edge.data.forward = input_edge.isBackward();
|
||||||
edge.data.backward = i->isForward();
|
edge.data.backward = input_edge.isForward();
|
||||||
edge.data.edgeBasedNodeID = edges.size();
|
|
||||||
edge.data.reversedEdge = true;
|
edge.data.reversedEdge = true;
|
||||||
edges.push_back( edge );
|
edge_list.push_back( edge );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::vector<NodeBasedEdge>().swap(inputEdges);
|
std::vector<NodeBasedEdge>().swap(input_edges);
|
||||||
std::sort( edges.begin(), edges.end() );
|
BOOST_ASSERT_MSG(
|
||||||
_nodeBasedGraph = boost::make_shared<TarjanDynamicGraph>( nodes, edges );
|
0 == input_edges.size() && 0 == input_edges.capacity(),
|
||||||
|
"input edge vector not properly deallocated"
|
||||||
|
);
|
||||||
|
|
||||||
|
std::sort( edge_list.begin(), edge_list.end() );
|
||||||
|
|
||||||
|
m_node_based_graph = boost::make_shared<TarjanDynamicGraph>(
|
||||||
|
number_of_nodes,
|
||||||
|
edge_list
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
~TarjanSCC() {
|
||||||
|
m_node_based_graph.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Run() {
|
void Run() {
|
||||||
@ -211,162 +220,203 @@ public:
|
|||||||
DeleteFileIfExists("component.shx");
|
DeleteFileIfExists("component.shx");
|
||||||
DeleteFileIfExists("component.shp");
|
DeleteFileIfExists("component.shp");
|
||||||
|
|
||||||
Percent p(_nodeBasedGraph->GetNumberOfNodes());
|
Percent p(m_node_based_graph->GetNumberOfNodes());
|
||||||
|
|
||||||
const char *pszDriverName = "ESRI Shapefile";
|
|
||||||
OGRSFDriver *poDriver;
|
|
||||||
|
|
||||||
OGRRegisterAll();
|
OGRRegisterAll();
|
||||||
|
|
||||||
poDriver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(
|
const char *pszDriverName = "ESRI Shapefile";
|
||||||
pszDriverName );
|
OGRSFDriver * poDriver = OGRSFDriverRegistrar::GetRegistrar()->
|
||||||
if( poDriver == NULL )
|
GetDriverByName( pszDriverName );
|
||||||
{
|
if( NULL == poDriver ) {
|
||||||
printf( "%s driver not available.\n", pszDriverName );
|
throw OSRMException("ESRI Shapefile driver not available");
|
||||||
exit( 1 );
|
|
||||||
}
|
}
|
||||||
OGRDataSource *poDS;
|
OGRDataSource * poDS = poDriver->CreateDataSource(
|
||||||
|
"component.shp",
|
||||||
poDS = poDriver->CreateDataSource( "component.shp", NULL );
|
NULL
|
||||||
if( poDS == NULL ) {
|
|
||||||
printf( "Creation of output file failed.\n" );
|
|
||||||
exit( 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
OGRLayer *poLayer;
|
|
||||||
|
|
||||||
poLayer = poDS->CreateLayer( "component", NULL, wkbLineString, NULL );
|
|
||||||
if( poLayer == NULL ) {
|
|
||||||
printf( "Layer creation failed.\n" );
|
|
||||||
exit( 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//The following is a hack to distinguish between stuff that happens before the recursive call and stuff that happens after
|
|
||||||
std::stack<std::pair<bool, TarjanStackFrame> > recursionStack; //true = stuff before, false = stuff after call
|
|
||||||
std::stack<NodeID> tarjanStack;
|
|
||||||
std::vector<unsigned> componentsIndex(_nodeBasedGraph->GetNumberOfNodes(), UINT_MAX);
|
|
||||||
std::vector<NodeID> vectorOfComponentSizes;
|
|
||||||
std::vector<TarjanNode> tarjanNodes(_nodeBasedGraph->GetNumberOfNodes());
|
|
||||||
unsigned currentComponent = 0, sizeOfCurrentComponent = 0;
|
|
||||||
int index = 0;
|
|
||||||
for(NodeID node = 0, endNodes = _nodeBasedGraph->GetNumberOfNodes(); node < endNodes; ++node) {
|
|
||||||
if(UINT_MAX == componentsIndex[node]) {
|
|
||||||
recursionStack.push(std::make_pair(true, TarjanStackFrame(node,node)) );
|
|
||||||
}
|
|
||||||
|
|
||||||
while(!recursionStack.empty()) {
|
|
||||||
bool beforeRecursion = recursionStack.top().first;
|
|
||||||
TarjanStackFrame currentFrame = recursionStack.top().second;
|
|
||||||
NodeID v = currentFrame.v;
|
|
||||||
// SimpleLogger().Write() << "popping node " << v << (beforeRecursion ? " before " : " after ") << "recursion";
|
|
||||||
recursionStack.pop();
|
|
||||||
|
|
||||||
if(beforeRecursion) {
|
|
||||||
//Mark frame to handle tail of recursion
|
|
||||||
recursionStack.push(std::make_pair(false, currentFrame));
|
|
||||||
|
|
||||||
//Mark essential information for SCC
|
|
||||||
tarjanNodes[v].index = index;
|
|
||||||
tarjanNodes[v].lowlink = index;
|
|
||||||
tarjanStack.push(v);
|
|
||||||
tarjanNodes[v].onStack = true;
|
|
||||||
++index;
|
|
||||||
// SimpleLogger().Write() << "pushing " << v << " onto tarjan stack, idx[" << v << "]=" << tarjanNodes[v].index << ", lowlink["<< v << "]=" << tarjanNodes[v].lowlink;
|
|
||||||
|
|
||||||
//Traverse outgoing edges
|
|
||||||
for(TarjanDynamicGraph::EdgeIterator e2 = _nodeBasedGraph->BeginEdges(v); e2 < _nodeBasedGraph->EndEdges(v); ++e2) {
|
|
||||||
TarjanDynamicGraph::NodeIterator vprime = _nodeBasedGraph->GetTarget(e2);
|
|
||||||
// SimpleLogger().Write() << "traversing edge (" << v << "," << vprime << ")";
|
|
||||||
if(UINT_MAX == tarjanNodes[vprime].index) {
|
|
||||||
|
|
||||||
recursionStack.push(std::make_pair(true,TarjanStackFrame(vprime, v)));
|
|
||||||
} else {
|
|
||||||
// SimpleLogger().Write() << "Node " << vprime << " is already explored";
|
|
||||||
if(tarjanNodes[vprime].onStack) {
|
|
||||||
unsigned newLowlink = std::min(tarjanNodes[v].lowlink, tarjanNodes[vprime].index);
|
|
||||||
// SimpleLogger().Write() << "Setting lowlink[" << v << "] from " << tarjanNodes[v].lowlink << " to " << newLowlink;
|
|
||||||
tarjanNodes[v].lowlink = newLowlink;
|
|
||||||
// } else {
|
|
||||||
// SimpleLogger().Write() << "But node " << vprime << " is not on stack";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// SimpleLogger().Write() << "we are at the end of recursion and checking node " << v;
|
|
||||||
{ // setting lowlink in its own scope so it does not pollute namespace
|
|
||||||
// NodeID parent = (UINT_MAX == tarjanNodes[v].parent ? v : tarjanNodes[v].parent );
|
|
||||||
// SimpleLogger().Write() << "parent=" << currentFrame.parent;
|
|
||||||
// SimpleLogger().Write() << "tarjanNodes[" << v << "].lowlink=" << tarjanNodes[v].lowlink << ", tarjanNodes[" << currentFrame.parent << "].lowlink=" << tarjanNodes[currentFrame.parent].lowlink;
|
|
||||||
//Note the index shift by 1 compared to the recursive version
|
|
||||||
tarjanNodes[currentFrame.parent].lowlink = std::min(tarjanNodes[currentFrame.parent].lowlink, tarjanNodes[v].lowlink);
|
|
||||||
// SimpleLogger().Write() << "Setting tarjanNodes[" << currentFrame.parent <<"].lowlink=" << tarjanNodes[currentFrame.parent].lowlink;
|
|
||||||
}
|
|
||||||
// SimpleLogger().Write() << "tarjanNodes[" << v << "].lowlink=" << tarjanNodes[v].lowlink << ", tarjanNodes[" << v << "].index=" << tarjanNodes[v].index;
|
|
||||||
|
|
||||||
//after recursion, lets do cycle checking
|
|
||||||
//Check if we found a cycle. This is the bottom part of the recursion
|
|
||||||
if(tarjanNodes[v].lowlink == tarjanNodes[v].index) {
|
|
||||||
NodeID vprime;
|
|
||||||
do {
|
|
||||||
// SimpleLogger().Write() << "identified component " << currentComponent << ": " << tarjanStack.top();
|
|
||||||
vprime = tarjanStack.top(); tarjanStack.pop();
|
|
||||||
tarjanNodes[vprime].onStack = false;
|
|
||||||
componentsIndex[vprime] = currentComponent;
|
|
||||||
++sizeOfCurrentComponent;
|
|
||||||
} while( v != vprime);
|
|
||||||
vectorOfComponentSizes.push_back(sizeOfCurrentComponent);
|
|
||||||
if(sizeOfCurrentComponent > 1000)
|
|
||||||
SimpleLogger().Write() << "large component [" << currentComponent << "]=" << sizeOfCurrentComponent;
|
|
||||||
++currentComponent;
|
|
||||||
sizeOfCurrentComponent = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SimpleLogger().Write() << "identified: " << vectorOfComponentSizes.size() << " many components, marking small components";
|
|
||||||
|
|
||||||
int singleCounter = 0;
|
|
||||||
for(unsigned i = 0; i < vectorOfComponentSizes.size(); ++i){
|
|
||||||
if(1 == vectorOfComponentSizes[i])
|
|
||||||
++singleCounter;
|
|
||||||
}
|
|
||||||
SimpleLogger().Write() << "identified " << singleCounter << " SCCs of size 1";
|
|
||||||
uint64_t total_network_distance = 0;
|
|
||||||
p.reinit(_nodeBasedGraph->GetNumberOfNodes());
|
|
||||||
for(TarjanDynamicGraph::NodeIterator u = 0; u < _nodeBasedGraph->GetNumberOfNodes(); ++u ) {
|
|
||||||
p.printIncrement();
|
|
||||||
for(TarjanDynamicGraph::EdgeIterator e1 = _nodeBasedGraph->BeginEdges(u); e1 < _nodeBasedGraph->EndEdges(u); ++e1) {
|
|
||||||
if(_nodeBasedGraph->GetEdgeData(e1).reversedEdge) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
TarjanDynamicGraph::NodeIterator v = _nodeBasedGraph->GetTarget(e1);
|
|
||||||
|
|
||||||
total_network_distance += 100*ApproximateDistance(
|
|
||||||
inputNodeInfoList[u].lat,
|
|
||||||
inputNodeInfoList[u].lon,
|
|
||||||
inputNodeInfoList[v].lat,
|
|
||||||
inputNodeInfoList[v].lon
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if(_nodeBasedGraph->GetEdgeData(e1).type != SHRT_MAX) {
|
if( NULL == poDS ) {
|
||||||
assert(e1 != UINT_MAX);
|
throw OSRMException("Creation of output file failed");
|
||||||
assert(u != UINT_MAX);
|
}
|
||||||
assert(v != UINT_MAX);
|
|
||||||
|
OGRLayer * poLayer = poDS->CreateLayer(
|
||||||
|
"component",
|
||||||
|
NULL,
|
||||||
|
wkbLineString,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if( NULL == poLayer ) {
|
||||||
|
throw OSRMException("Layer creation failed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
//The following is a hack to distinguish between stuff that happens
|
||||||
|
//before the recursive call and stuff that happens after
|
||||||
|
std::stack<std::pair<bool, TarjanStackFrame> > recursion_stack;
|
||||||
|
//true = stuff before, false = stuff after call
|
||||||
|
std::stack<NodeID> tarjan_stack;
|
||||||
|
std::vector<unsigned> components_index(
|
||||||
|
m_node_based_graph->GetNumberOfNodes(),
|
||||||
|
UINT_MAX
|
||||||
|
);
|
||||||
|
std::vector<NodeID> component_size_vector;
|
||||||
|
std::vector<TarjanNode> tarjan_node_list(
|
||||||
|
m_node_based_graph->GetNumberOfNodes()
|
||||||
|
);
|
||||||
|
unsigned component_index = 0, size_of_current_component = 0;
|
||||||
|
int index = 0;
|
||||||
|
for(
|
||||||
|
NodeID node = 0, last_node = m_node_based_graph->GetNumberOfNodes();
|
||||||
|
node < last_node;
|
||||||
|
++node
|
||||||
|
) {
|
||||||
|
if(UINT_MAX == components_index[node]) {
|
||||||
|
recursion_stack.push(
|
||||||
|
std::make_pair(true, TarjanStackFrame(node,node))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
while(!recursion_stack.empty()) {
|
||||||
|
bool before_recursion = recursion_stack.top().first;
|
||||||
|
TarjanStackFrame currentFrame = recursion_stack.top().second;
|
||||||
|
NodeID v = currentFrame.v;
|
||||||
|
recursion_stack.pop();
|
||||||
|
|
||||||
|
if(before_recursion) {
|
||||||
|
//Mark frame to handle tail of recursion
|
||||||
|
recursion_stack.push(std::make_pair(false, currentFrame));
|
||||||
|
|
||||||
|
//Mark essential information for SCC
|
||||||
|
tarjan_node_list[v].index = index;
|
||||||
|
tarjan_node_list[v].lowlink = index;
|
||||||
|
tarjan_stack.push(v);
|
||||||
|
tarjan_node_list[v].onStack = true;
|
||||||
|
++index;
|
||||||
|
|
||||||
|
//Traverse outgoing edges
|
||||||
|
for(
|
||||||
|
TarjanDynamicGraph::EdgeIterator e2 = m_node_based_graph->BeginEdges(v);
|
||||||
|
e2 < m_node_based_graph->EndEdges(v);
|
||||||
|
++e2
|
||||||
|
) {
|
||||||
|
const TarjanDynamicGraph::NodeIterator vprime =
|
||||||
|
m_node_based_graph->GetTarget(e2);
|
||||||
|
if(UINT_MAX == tarjan_node_list[vprime].index) {
|
||||||
|
recursion_stack.push(
|
||||||
|
std::make_pair(
|
||||||
|
true,
|
||||||
|
TarjanStackFrame(vprime, v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
if(
|
||||||
|
tarjan_node_list[vprime].onStack &&
|
||||||
|
tarjan_node_list[vprime].index < tarjan_node_list[v].lowlink
|
||||||
|
) {
|
||||||
|
tarjan_node_list[v].lowlink = tarjan_node_list[vprime].index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tarjan_node_list[currentFrame.parent].lowlink =
|
||||||
|
std::min(
|
||||||
|
tarjan_node_list[currentFrame.parent].lowlink,
|
||||||
|
tarjan_node_list[v].lowlink
|
||||||
|
);
|
||||||
|
//after recursion, lets do cycle checking
|
||||||
|
//Check if we found a cycle. This is the bottom part of the recursion
|
||||||
|
if(tarjan_node_list[v].lowlink == tarjan_node_list[v].index) {
|
||||||
|
NodeID vprime;
|
||||||
|
do {
|
||||||
|
vprime = tarjan_stack.top(); tarjan_stack.pop();
|
||||||
|
tarjan_node_list[vprime].onStack = false;
|
||||||
|
components_index[vprime] = component_index;
|
||||||
|
++size_of_current_component;
|
||||||
|
} while( v != vprime);
|
||||||
|
|
||||||
|
component_size_vector.push_back(size_of_current_component);
|
||||||
|
|
||||||
|
if(size_of_current_component > 1000) {
|
||||||
|
SimpleLogger().Write() <<
|
||||||
|
"large component [" << component_index << "]=" <<
|
||||||
|
size_of_current_component;
|
||||||
|
}
|
||||||
|
|
||||||
|
++component_index;
|
||||||
|
size_of_current_component = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleLogger().Write() <<
|
||||||
|
"identified: " << component_size_vector.size() <<
|
||||||
|
" many components, marking small components";
|
||||||
|
|
||||||
|
unsigned size_one_counter = 0;
|
||||||
|
for(unsigned i = 0, end = component_size_vector.size(); i < end; ++i){
|
||||||
|
if(1 == component_size_vector[i]) {
|
||||||
|
++size_one_counter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleLogger().Write() <<
|
||||||
|
"identified " << size_one_counter << " SCCs of size 1";
|
||||||
|
|
||||||
|
uint64_t total_network_distance = 0;
|
||||||
|
p.reinit(m_node_based_graph->GetNumberOfNodes());
|
||||||
|
for(
|
||||||
|
TarjanDynamicGraph::NodeIterator u = 0, last_u_node = m_node_based_graph->GetNumberOfNodes();
|
||||||
|
u < last_u_node;
|
||||||
|
++u
|
||||||
|
) {
|
||||||
|
p.printIncrement();
|
||||||
|
for(
|
||||||
|
TarjanDynamicGraph::EdgeIterator e1 = m_node_based_graph->BeginEdges(u), last_edge = m_node_based_graph->EndEdges(u);
|
||||||
|
e1 < last_edge;
|
||||||
|
++e1
|
||||||
|
) {
|
||||||
|
if(!m_node_based_graph->GetEdgeData(e1).reversedEdge) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const TarjanDynamicGraph::NodeIterator v = m_node_based_graph->GetTarget(e1);
|
||||||
|
|
||||||
|
total_network_distance += 100*ApproximateDistance(
|
||||||
|
m_coordinate_list[u].lat,
|
||||||
|
m_coordinate_list[u].lon,
|
||||||
|
m_coordinate_list[v].lat,
|
||||||
|
m_coordinate_list[v].lon
|
||||||
|
);
|
||||||
|
|
||||||
|
if( SHRT_MAX != m_node_based_graph->GetEdgeData(e1).type ) {
|
||||||
|
BOOST_ASSERT(e1 != UINT_MAX);
|
||||||
|
BOOST_ASSERT(u != UINT_MAX);
|
||||||
|
BOOST_ASSERT(v != UINT_MAX);
|
||||||
|
|
||||||
|
const unsigned size_of_containing_component =
|
||||||
|
std::min(
|
||||||
|
component_size_vector[components_index[u]],
|
||||||
|
component_size_vector[components_index[v]]
|
||||||
|
);
|
||||||
|
|
||||||
//edges that end on bollard nodes may actually be in two distinct components
|
//edges that end on bollard nodes may actually be in two distinct components
|
||||||
if(std::min(vectorOfComponentSizes[componentsIndex[u]], vectorOfComponentSizes[componentsIndex[v]]) < 10) {
|
if(size_of_containing_component < 10) {
|
||||||
|
|
||||||
//INFO("(" << inputNodeInfoList[u].lat/COORDINATE_PRECISION << ";" << inputNodeInfoList[u].lon/COORDINATE_PRECISION << ") -> (" << inputNodeInfoList[v].lat/COORDINATE_PRECISION << ";" << inputNodeInfoList[v].lon/COORDINATE_PRECISION << ")");
|
|
||||||
OGRLineString lineString;
|
OGRLineString lineString;
|
||||||
lineString.addPoint(inputNodeInfoList[u].lon/COORDINATE_PRECISION, inputNodeInfoList[u].lat/COORDINATE_PRECISION);
|
lineString.addPoint(
|
||||||
lineString.addPoint(inputNodeInfoList[v].lon/COORDINATE_PRECISION, inputNodeInfoList[v].lat/COORDINATE_PRECISION);
|
m_coordinate_list[u].lon/COORDINATE_PRECISION,
|
||||||
OGRFeature *poFeature;
|
m_coordinate_list[u].lat/COORDINATE_PRECISION
|
||||||
poFeature = OGRFeature::CreateFeature( poLayer->GetLayerDefn() );
|
);
|
||||||
|
lineString.addPoint(
|
||||||
|
m_coordinate_list[v].lon/COORDINATE_PRECISION,
|
||||||
|
m_coordinate_list[v].lat/COORDINATE_PRECISION
|
||||||
|
);
|
||||||
|
|
||||||
|
OGRFeature * poFeature = OGRFeature::CreateFeature(
|
||||||
|
poLayer->GetLayerDefn()
|
||||||
|
);
|
||||||
|
|
||||||
poFeature->SetGeometry( &lineString );
|
poFeature->SetGeometry( &lineString );
|
||||||
if( poLayer->CreateFeature( poFeature ) != OGRERR_NONE ) {
|
if( OGRERR_NONE != poLayer->CreateFeature(poFeature) ) {
|
||||||
throw OSRMException(
|
throw OSRMException(
|
||||||
"Failed to create feature in shapefile."
|
"Failed to create feature in shapefile."
|
||||||
);
|
);
|
||||||
@ -377,39 +427,66 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
OGRDataSource::DestroyDataSource( poDS );
|
OGRDataSource::DestroyDataSource( poDS );
|
||||||
std::vector<NodeID>().swap(vectorOfComponentSizes);
|
std::vector<NodeID>().swap(component_size_vector);
|
||||||
std::vector<NodeID>().swap(componentsIndex);
|
BOOST_ASSERT_MSG(
|
||||||
SimpleLogger().Write() << "total network distance: " << (uint64_t)total_network_distance/100/1000. << " km";
|
0 == component_size_vector.size() &&
|
||||||
|
0 == component_size_vector.capacity(),
|
||||||
|
"component_size_vector not properly deallocated"
|
||||||
|
);
|
||||||
|
|
||||||
|
std::vector<NodeID>().swap(components_index);
|
||||||
|
BOOST_ASSERT_MSG(
|
||||||
|
0 == components_index.size() && 0 == components_index.capacity(),
|
||||||
|
"icomponents_index not properly deallocated"
|
||||||
|
);
|
||||||
|
|
||||||
|
SimpleLogger().Write()
|
||||||
|
<< "total network distance: " <<
|
||||||
|
(uint64_t)total_network_distance/100/1000. <<
|
||||||
|
" km";
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const {
|
unsigned CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const {
|
||||||
std::pair < NodeID, NodeID > restrictionSource = std::make_pair(u, v);
|
std::pair < NodeID, NodeID > restriction_source = std::make_pair(u, v);
|
||||||
RestrictionMap::const_iterator restrIter = _restrictionMap.find(restrictionSource);
|
RestrictionMap::const_iterator restriction_iterator = m_restriction_map.find(restriction_source);
|
||||||
if (restrIter != _restrictionMap.end()) {
|
if (restriction_iterator != m_restriction_map.end()) {
|
||||||
unsigned index = restrIter->second;
|
const unsigned index = restriction_iterator->second;
|
||||||
BOOST_FOREACH(RestrictionSource restrictionTarget, _restrictionBucketVector.at(index)) {
|
BOOST_FOREACH(
|
||||||
if(restrictionTarget.second) {
|
const RestrictionSource & restriction_target,
|
||||||
return restrictionTarget.first;
|
m_restriction_bucket_list.at(index)
|
||||||
|
) {
|
||||||
|
if(restriction_target.second) {
|
||||||
|
return restriction_target.first;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return UINT_MAX;
|
return UINT_MAX;
|
||||||
}
|
}
|
||||||
bool CheckIfTurnIsRestricted(const NodeID u, const NodeID v, const NodeID w) const {
|
|
||||||
|
bool CheckIfTurnIsRestricted(
|
||||||
|
const NodeID u,
|
||||||
|
const NodeID v,
|
||||||
|
const NodeID w
|
||||||
|
) const {
|
||||||
//only add an edge if turn is not a U-turn except it is the end of dead-end street.
|
//only add an edge if turn is not a U-turn except it is the end of dead-end street.
|
||||||
std::pair < NodeID, NodeID > restrictionSource = std::make_pair(u, v);
|
std::pair < NodeID, NodeID > restriction_source = std::make_pair(u, v);
|
||||||
RestrictionMap::const_iterator restrIter = _restrictionMap.find(restrictionSource);
|
RestrictionMap::const_iterator restriction_iterator = m_restriction_map.find(restriction_source);
|
||||||
if (restrIter != _restrictionMap.end()) {
|
if (restriction_iterator != m_restriction_map.end()) {
|
||||||
unsigned index = restrIter->second;
|
const unsigned index = restriction_iterator->second;
|
||||||
BOOST_FOREACH(RestrictionTarget restrictionTarget, _restrictionBucketVector.at(index)) {
|
BOOST_FOREACH(
|
||||||
if(w == restrictionTarget.first)
|
const restriction_target & restriction_target,
|
||||||
|
m_restriction_bucket_list.at(index)
|
||||||
|
) {
|
||||||
|
if(w == restriction_target.first) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeleteFileIfExists(const std::string file_name) const {
|
void DeleteFileIfExists(const std::string & file_name) const {
|
||||||
if (boost::filesystem::exists(file_name) ) {
|
if (boost::filesystem::exists(file_name) ) {
|
||||||
boost::filesystem::remove(file_name);
|
boost::filesystem::remove(file_name);
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 2.6)
|
|||||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
project(OSRM)
|
project(OSRM)
|
||||||
include(FindPackageHandleStandardArgs)
|
include(FindPackageHandleStandardArgs)
|
||||||
|
set(HUGO "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||||
|
|
||||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
||||||
include(GetGitRevisionDescription)
|
include(GetGitRevisionDescription)
|
||||||
@ -19,8 +20,8 @@ endif(IS_64_SYSTEM)
|
|||||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
|
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
|
||||||
|
|
||||||
add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/Util/UUID.cpp UUID.cpp.alwaysbuild
|
add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/Util/UUID.cpp UUID.cpp.alwaysbuild
|
||||||
COMMAND ${CMAKE_COMMAND} -P
|
COMMAND ${CMAKE_COMMAND} -DSOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
${CMAKE_SOURCE_DIR}/cmake/UUID-Config.cmake
|
-P ${CMAKE_SOURCE_DIR}/cmake/UUID-Config.cmake
|
||||||
DEPENDS
|
DEPENDS
|
||||||
${CMAKE_SOURCE_DIR}/Util/UUID.cpp.in
|
${CMAKE_SOURCE_DIR}/Util/UUID.cpp.in
|
||||||
${CMAKE_SOURCE_DIR}/cmake/UUID-Config.cmake
|
${CMAKE_SOURCE_DIR}/cmake/UUID-Config.cmake
|
||||||
|
@ -21,52 +21,56 @@
|
|||||||
#include "EdgeBasedGraphFactory.h"
|
#include "EdgeBasedGraphFactory.h"
|
||||||
|
|
||||||
EdgeBasedGraphFactory::EdgeBasedGraphFactory(
|
EdgeBasedGraphFactory::EdgeBasedGraphFactory(
|
||||||
int nodes, std::vector<ImportEdge> & inputEdges,
|
int number_of_nodes,
|
||||||
|
std::vector<ImportEdge> & input_edge_list,
|
||||||
std::vector<NodeID> & barrier_node_list,
|
std::vector<NodeID> & barrier_node_list,
|
||||||
std::vector<NodeID> & traffic_light_node_list,
|
std::vector<NodeID> & traffic_light_node_list,
|
||||||
std::vector<TurnRestriction> & input_restrictions_list,
|
std::vector<TurnRestriction> & input_restrictions_list,
|
||||||
std::vector<NodeInfo> & inputNodeInfoList,
|
std::vector<NodeInfo> & m_node_info_list,
|
||||||
SpeedProfileProperties speedProfile
|
SpeedProfileProperties speed_profile
|
||||||
) : speedProfile(speedProfile),
|
) : speed_profile(speed_profile),
|
||||||
m_turn_restrictions_count(0),
|
m_turn_restrictions_count(0),
|
||||||
inputNodeInfoList(inputNodeInfoList)
|
m_node_info_list(m_node_info_list)
|
||||||
{
|
{
|
||||||
BOOST_FOREACH(const TurnRestriction & restriction, input_restrictions_list) {
|
BOOST_FOREACH(const TurnRestriction & restriction, input_restrictions_list) {
|
||||||
std::pair<NodeID, NodeID> restrictionSource = std::make_pair(restriction.fromNode, restriction.viaNode);
|
std::pair<NodeID, NodeID> restriction_source =
|
||||||
|
std::make_pair(restriction.fromNode, restriction.viaNode);
|
||||||
unsigned index;
|
unsigned index;
|
||||||
RestrictionMap::iterator restrIter = _restrictionMap.find(restrictionSource);
|
RestrictionMap::iterator restriction_iter = m_restriction_map.find(restriction_source);
|
||||||
if(restrIter == _restrictionMap.end()) {
|
if(restriction_iter == m_restriction_map.end()) {
|
||||||
index = _restrictionBucketVector.size();
|
index = m_restriction_bucket_list.size();
|
||||||
_restrictionBucketVector.resize(index+1);
|
m_restriction_bucket_list.resize(index+1);
|
||||||
_restrictionMap[restrictionSource] = index;
|
m_restriction_map[restriction_source] = index;
|
||||||
} else {
|
} else {
|
||||||
index = restrIter->second;
|
index = restriction_iter->second;
|
||||||
//Map already contains an is_only_*-restriction
|
//Map already contains an is_only_*-restriction
|
||||||
if(_restrictionBucketVector.at(index).begin()->second)
|
if(m_restriction_bucket_list.at(index).begin()->second) {
|
||||||
continue;
|
continue;
|
||||||
else if(restriction.flags.isOnly){
|
} else if(restriction.flags.isOnly) {
|
||||||
//We are going to insert an is_only_*-restriction. There can be only one.
|
//We are going to insert an is_only_*-restriction. There can be only one.
|
||||||
m_turn_restrictions_count -= _restrictionBucketVector.at(index).size();
|
m_turn_restrictions_count -= m_restriction_bucket_list.at(index).size();
|
||||||
_restrictionBucketVector.at(index).clear();
|
m_restriction_bucket_list.at(index).clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++m_turn_restrictions_count;
|
++m_turn_restrictions_count;
|
||||||
_restrictionBucketVector.at(index).push_back(std::make_pair(restriction.toNode, restriction.flags.isOnly));
|
m_restriction_bucket_list.at(index).push_back(
|
||||||
|
std::make_pair( restriction.toNode, restriction.flags.isOnly)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_barrierNodes.insert(
|
m_barrier_nodes.insert(
|
||||||
barrier_node_list.begin(),
|
barrier_node_list.begin(),
|
||||||
barrier_node_list.end()
|
barrier_node_list.end()
|
||||||
);
|
);
|
||||||
|
|
||||||
_trafficLights.insert(
|
m_traffic_lights.insert(
|
||||||
traffic_light_node_list.begin(),
|
traffic_light_node_list.begin(),
|
||||||
traffic_light_node_list.end()
|
traffic_light_node_list.end()
|
||||||
);
|
);
|
||||||
|
|
||||||
DeallocatingVector< _NodeBasedEdge > edges;
|
DeallocatingVector< NodeBasedEdge > edges_list;
|
||||||
_NodeBasedEdge edge;
|
NodeBasedEdge edge;
|
||||||
BOOST_FOREACH(const ImportEdge & import_edge, inputEdges) {
|
BOOST_FOREACH(const ImportEdge & import_edge, input_edge_list) {
|
||||||
if(!import_edge.isForward()) {
|
if(!import_edge.isForward()) {
|
||||||
edge.source = import_edge.target();
|
edge.source = import_edge.target();
|
||||||
edge.target = import_edge.source();
|
edge.target = import_edge.source();
|
||||||
@ -89,139 +93,189 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(
|
|||||||
edge.data.nameID = import_edge.name();
|
edge.data.nameID = import_edge.name();
|
||||||
edge.data.type = import_edge.type();
|
edge.data.type = import_edge.type();
|
||||||
edge.data.isAccessRestricted = import_edge.isAccessRestricted();
|
edge.data.isAccessRestricted = import_edge.isAccessRestricted();
|
||||||
edge.data.edgeBasedNodeID = edges.size();
|
edge.data.edgeBasedNodeID = edges_list.size();
|
||||||
edge.data.contraFlow = import_edge.isContraFlow();
|
edge.data.contraFlow = import_edge.isContraFlow();
|
||||||
edges.push_back( edge );
|
edges_list.push_back( edge );
|
||||||
if( edge.data.backward ) {
|
if( edge.data.backward ) {
|
||||||
std::swap( edge.source, edge.target );
|
std::swap( edge.source, edge.target );
|
||||||
edge.data.forward = import_edge.isBackward();
|
edge.data.forward = import_edge.isBackward();
|
||||||
edge.data.backward = import_edge.isForward();
|
edge.data.backward = import_edge.isForward();
|
||||||
edge.data.edgeBasedNodeID = edges.size();
|
edge.data.edgeBasedNodeID = edges_list.size();
|
||||||
edges.push_back( edge );
|
edges_list.push_back( edge );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::vector<ImportEdge>().swap(inputEdges);
|
std::vector<ImportEdge>().swap(input_edge_list);
|
||||||
std::sort( edges.begin(), edges.end() );
|
std::sort( edges_list.begin(), edges_list.end() );
|
||||||
_nodeBasedGraph = boost::make_shared<_NodeBasedDynamicGraph>( nodes, edges );
|
m_node_based_graph = boost::make_shared<NodeBasedDynamicGraph>(
|
||||||
|
number_of_nodes, edges_list
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EdgeBasedGraphFactory::GetEdgeBasedEdges(DeallocatingVector< EdgeBasedEdge >& outputEdgeList ) {
|
void EdgeBasedGraphFactory::GetEdgeBasedEdges(
|
||||||
|
DeallocatingVector< EdgeBasedEdge >& output_edge_list
|
||||||
|
) {
|
||||||
BOOST_ASSERT_MSG(
|
BOOST_ASSERT_MSG(
|
||||||
0 == outputEdgeList.size(),
|
0 == output_edge_list.size(),
|
||||||
"Vector is not empty"
|
"Vector is not empty"
|
||||||
);
|
);
|
||||||
edgeBasedEdges.swap(outputEdgeList);
|
m_edge_based_edge_list.swap(output_edge_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EdgeBasedGraphFactory::GetEdgeBasedNodes( std::vector<EdgeBasedNode> & nodes) {
|
void EdgeBasedGraphFactory::GetEdgeBasedNodes( std::vector<EdgeBasedNode> & nodes) {
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
BOOST_FOREACH(const EdgeBasedNode & node, edgeBasedNodes){
|
BOOST_FOREACH(const EdgeBasedNode & node, m_edge_based_node_list){
|
||||||
assert(node.lat1 != INT_MAX); assert(node.lon1 != INT_MAX);
|
assert(node.lat1 != INT_MAX); assert(node.lon1 != INT_MAX);
|
||||||
assert(node.lat2 != INT_MAX); assert(node.lon2 != INT_MAX);
|
assert(node.lat2 != INT_MAX); assert(node.lon2 != INT_MAX);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
nodes.swap(edgeBasedNodes);
|
nodes.swap(m_edge_based_node_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeID EdgeBasedGraphFactory::CheckForEmanatingIsOnlyTurn(
|
NodeID EdgeBasedGraphFactory::CheckForEmanatingIsOnlyTurn(
|
||||||
const NodeID u,
|
const NodeID u,
|
||||||
const NodeID v
|
const NodeID v
|
||||||
) const {
|
) const {
|
||||||
const std::pair < NodeID, NodeID > restrictionSource = std::make_pair(u, v);
|
const std::pair < NodeID, NodeID > restriction_source = std::make_pair(u, v);
|
||||||
RestrictionMap::const_iterator restrIter = _restrictionMap.find(restrictionSource);
|
RestrictionMap::const_iterator restriction_iter = m_restriction_map.find(restriction_source);
|
||||||
if (restrIter != _restrictionMap.end()) {
|
if (restriction_iter != m_restriction_map.end()) {
|
||||||
const unsigned index = restrIter->second;
|
const unsigned index = restriction_iter->second;
|
||||||
BOOST_FOREACH(const RestrictionSource & restrictionTarget, _restrictionBucketVector.at(index)) {
|
BOOST_FOREACH(
|
||||||
if(restrictionTarget.second) {
|
const RestrictionSource & restriction_target,
|
||||||
return restrictionTarget.first;
|
m_restriction_bucket_list.at(index)
|
||||||
|
) {
|
||||||
|
if(restriction_target.second) {
|
||||||
|
return restriction_target.first;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return UINT_MAX;
|
return UINT_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EdgeBasedGraphFactory::CheckIfTurnIsRestricted(const NodeID u, const NodeID v, const NodeID w) const {
|
bool EdgeBasedGraphFactory::CheckIfTurnIsRestricted(
|
||||||
|
const NodeID u,
|
||||||
|
const NodeID v,
|
||||||
|
const NodeID w
|
||||||
|
) const {
|
||||||
//only add an edge if turn is not a U-turn except it is the end of dead-end street.
|
//only add an edge if turn is not a U-turn except it is the end of dead-end street.
|
||||||
const std::pair < NodeID, NodeID > restrictionSource = std::make_pair(u, v);
|
const std::pair < NodeID, NodeID > restriction_source = std::make_pair(u, v);
|
||||||
RestrictionMap::const_iterator restrIter = _restrictionMap.find(restrictionSource);
|
RestrictionMap::const_iterator restriction_iter = m_restriction_map.find(restriction_source);
|
||||||
if (restrIter != _restrictionMap.end()) {
|
if (restriction_iter != m_restriction_map.end()) {
|
||||||
const unsigned index = restrIter->second;
|
const unsigned index = restriction_iter->second;
|
||||||
BOOST_FOREACH(const RestrictionTarget & restrictionTarget, _restrictionBucketVector.at(index)) {
|
BOOST_FOREACH(
|
||||||
if(w == restrictionTarget.first)
|
const RestrictionTarget & restriction_target,
|
||||||
|
m_restriction_bucket_list.at(index)
|
||||||
|
) {
|
||||||
|
if(w == restriction_target.first) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EdgeBasedGraphFactory::InsertEdgeBasedNode(
|
void EdgeBasedGraphFactory::InsertEdgeBasedNode(
|
||||||
_NodeBasedDynamicGraph::EdgeIterator e1,
|
EdgeIterator e1,
|
||||||
_NodeBasedDynamicGraph::NodeIterator u,
|
NodeIterator u,
|
||||||
_NodeBasedDynamicGraph::NodeIterator v,
|
NodeIterator v,
|
||||||
bool belongsToTinyComponent) {
|
bool belongsToTinyComponent) {
|
||||||
_NodeBasedDynamicGraph::EdgeData & data = _nodeBasedGraph->GetEdgeData(e1);
|
EdgeData & data = m_node_based_graph->GetEdgeData(e1);
|
||||||
EdgeBasedNode currentNode;
|
EdgeBasedNode currentNode;
|
||||||
currentNode.nameID = data.nameID;
|
currentNode.nameID = data.nameID;
|
||||||
currentNode.lat1 = inputNodeInfoList[u].lat;
|
currentNode.lat1 = m_node_info_list[u].lat;
|
||||||
currentNode.lon1 = inputNodeInfoList[u].lon;
|
currentNode.lon1 = m_node_info_list[u].lon;
|
||||||
currentNode.lat2 = inputNodeInfoList[v].lat;
|
currentNode.lat2 = m_node_info_list[v].lat;
|
||||||
currentNode.lon2 = inputNodeInfoList[v].lon;
|
currentNode.lon2 = m_node_info_list[v].lon;
|
||||||
currentNode.belongsToTinyComponent = belongsToTinyComponent;
|
currentNode.belongsToTinyComponent = belongsToTinyComponent;
|
||||||
currentNode.id = data.edgeBasedNodeID;
|
currentNode.id = data.edgeBasedNodeID;
|
||||||
currentNode.ignoreInGrid = data.ignoreInGrid;
|
currentNode.ignoreInGrid = data.ignoreInGrid;
|
||||||
currentNode.weight = data.distance;
|
currentNode.weight = data.distance;
|
||||||
edgeBasedNodes.push_back(currentNode);
|
m_edge_based_node_list.push_back(currentNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EdgeBasedGraphFactory::Run(const char * originalEdgeDataFilename, lua_State *myLuaState) {
|
void EdgeBasedGraphFactory::Run(
|
||||||
Percent p(_nodeBasedGraph->GetNumberOfNodes());
|
const char * original_edge_data_filename,
|
||||||
int numberOfSkippedTurns(0);
|
lua_State *lua_state
|
||||||
int nodeBasedEdgeCounter(0);
|
) {
|
||||||
unsigned numberOfOriginalEdges(0);
|
SimpleLogger().Write() << "Identifying components of the road network";
|
||||||
std::ofstream originalEdgeDataOutFile(originalEdgeDataFilename, std::ios::binary);
|
|
||||||
originalEdgeDataOutFile.write((char*)&numberOfOriginalEdges, sizeof(unsigned));
|
|
||||||
|
|
||||||
|
Percent p(m_node_based_graph->GetNumberOfNodes());
|
||||||
|
unsigned skipped_turns_counter = 0;
|
||||||
|
unsigned node_based_edge_counter = 0;
|
||||||
|
unsigned original_edges_counter = 0;
|
||||||
|
|
||||||
SimpleLogger().Write() << "Identifying small components";
|
std::ofstream edge_data_file(
|
||||||
|
original_edge_data_filename,
|
||||||
|
std::ios::binary
|
||||||
|
);
|
||||||
|
|
||||||
|
//writes a dummy value that is updated later
|
||||||
|
edge_data_file.write(
|
||||||
|
(char*)&original_edges_counter,
|
||||||
|
sizeof(unsigned)
|
||||||
|
);
|
||||||
|
|
||||||
|
unsigned current_component = 0, current_component_size = 0;
|
||||||
//Run a BFS on the undirected graph and identify small components
|
//Run a BFS on the undirected graph and identify small components
|
||||||
std::queue<std::pair<NodeID, NodeID> > bfsQueue;
|
std::queue<std::pair<NodeID, NodeID> > bfs_queue;
|
||||||
std::vector<unsigned> componentsIndex(_nodeBasedGraph->GetNumberOfNodes(), UINT_MAX);
|
std::vector<unsigned> component_index_list(
|
||||||
std::vector<NodeID> vectorOfComponentSizes;
|
m_node_based_graph->GetNumberOfNodes(),
|
||||||
unsigned currentComponent = 0, sizeOfCurrentComponent = 0;
|
UINT_MAX
|
||||||
|
);
|
||||||
|
|
||||||
|
std::vector<NodeID> component_size_list;
|
||||||
//put unexplorered node with parent pointer into queue
|
//put unexplorered node with parent pointer into queue
|
||||||
for(NodeID node = 0, endNodes = _nodeBasedGraph->GetNumberOfNodes(); node < endNodes; ++node) {
|
for(
|
||||||
if(UINT_MAX == componentsIndex[node]) {
|
NodeID node = 0,
|
||||||
bfsQueue.push(std::make_pair(node, node));
|
last_node = m_node_based_graph->GetNumberOfNodes();
|
||||||
|
node < last_node;
|
||||||
|
++node
|
||||||
|
) {
|
||||||
|
if(UINT_MAX == component_index_list[node]) {
|
||||||
|
bfs_queue.push(std::make_pair(node, node));
|
||||||
//mark node as read
|
//mark node as read
|
||||||
componentsIndex[node] = currentComponent;
|
component_index_list[node] = current_component;
|
||||||
p.printIncrement();
|
p.printIncrement();
|
||||||
while(!bfsQueue.empty()) {
|
while(!bfs_queue.empty()) {
|
||||||
//fetch element from BFS queue
|
//fetch element from BFS queue
|
||||||
std::pair<NodeID, NodeID> currentQueueItem = bfsQueue.front();
|
std::pair<NodeID, NodeID> current_queue_item = bfs_queue.front();
|
||||||
bfsQueue.pop();
|
bfs_queue.pop();
|
||||||
// SimpleLogger().Write() << "sizeof queue: " << bfsQueue.size() << ", sizeOfCurrentComponents: " << sizeOfCurrentComponent << ", settled nodes: " << settledNodes++ << ", max: " << endNodes;
|
// SimpleLogger().Write() << "sizeof queue: " << bfs_queue.size() <<
|
||||||
const NodeID v = currentQueueItem.first; //current node
|
// ", current_component_sizes: " << current_component_size <<
|
||||||
const NodeID u = currentQueueItem.second; //parent
|
//", settled nodes: " << settledNodes++ << ", max: " << endNodes;
|
||||||
|
const NodeID v = current_queue_item.first; //current node
|
||||||
|
const NodeID u = current_queue_item.second; //parent
|
||||||
//increment size counter of current component
|
//increment size counter of current component
|
||||||
++sizeOfCurrentComponent;
|
++current_component_size;
|
||||||
const bool isBollardNode = (_barrierNodes.find(v) != _barrierNodes.end());
|
const bool is_barrier_node = (m_barrier_nodes.find(v) != m_barrier_nodes.end());
|
||||||
if(!isBollardNode) {
|
if(!is_barrier_node) {
|
||||||
const NodeID onlyToNode = CheckForEmanatingIsOnlyTurn(u, v);
|
const NodeID to_node_of_only_restriction = CheckForEmanatingIsOnlyTurn(u, v);
|
||||||
|
|
||||||
//relaxieren edge outgoing edge like below where edge-expanded graph
|
//relaxieren edge outgoing edge like below where edge-expanded graph
|
||||||
for(_NodeBasedDynamicGraph::EdgeIterator e2 = _nodeBasedGraph->BeginEdges(v); e2 < _nodeBasedGraph->EndEdges(v); ++e2) {
|
for(
|
||||||
_NodeBasedDynamicGraph::NodeIterator w = _nodeBasedGraph->GetTarget(e2);
|
EdgeIterator e2 = m_node_based_graph->BeginEdges(v);
|
||||||
|
e2 < m_node_based_graph->EndEdges(v);
|
||||||
|
++e2
|
||||||
|
) {
|
||||||
|
NodeIterator w = m_node_based_graph->GetTarget(e2);
|
||||||
|
|
||||||
if(onlyToNode != UINT_MAX && w != onlyToNode) { //We are at an only_-restriction but not at the right turn.
|
if(
|
||||||
|
to_node_of_only_restriction != UINT_MAX &&
|
||||||
|
w != to_node_of_only_restriction
|
||||||
|
) {
|
||||||
|
//We are at an only_-restriction but not at the right turn.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if( u != w ) { //only add an edge if turn is not a U-turn except it is the end of dead-end street.
|
if( u != w ) {
|
||||||
if (!CheckIfTurnIsRestricted(u, v, w) ) { //only add an edge if turn is not prohibited
|
//only add an edge if turn is not a U-turn except
|
||||||
//insert next (node, parent) only if w has not yet been explored
|
//when it is at the end of a dead-end street.
|
||||||
if(UINT_MAX == componentsIndex[w]) {
|
if (!CheckIfTurnIsRestricted(u, v, w) ) {
|
||||||
|
//only add an edge if turn is not prohibited
|
||||||
|
if(UINT_MAX == component_index_list[w]) {
|
||||||
|
//insert next (node, parent) only if w has
|
||||||
|
//not yet been explored
|
||||||
//mark node as read
|
//mark node as read
|
||||||
componentsIndex[w] = currentComponent;
|
component_index_list[w] = current_component;
|
||||||
bfsQueue.push(std::make_pair(w,v));
|
bfs_queue.push(std::make_pair(w,v));
|
||||||
p.printIncrement();
|
p.printIncrement();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -230,142 +284,214 @@ void EdgeBasedGraphFactory::Run(const char * originalEdgeDataFilename, lua_State
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//push size into vector
|
//push size into vector
|
||||||
vectorOfComponentSizes.push_back(sizeOfCurrentComponent);
|
component_size_list.push_back(current_component_size);
|
||||||
//reset counters;
|
//reset counters;
|
||||||
sizeOfCurrentComponent = 0;
|
current_component_size = 0;
|
||||||
++currentComponent;
|
++current_component;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SimpleLogger().Write() << "identified: " << vectorOfComponentSizes.size() << " many components";
|
SimpleLogger().Write() <<
|
||||||
|
"identified: " << component_size_list.size() << " many components";
|
||||||
|
SimpleLogger().Write() <<
|
||||||
|
"generating edge-expanded nodes";
|
||||||
|
|
||||||
p.reinit(_nodeBasedGraph->GetNumberOfNodes());
|
p.reinit(m_node_based_graph->GetNumberOfNodes());
|
||||||
//loop over all edges and generate new set of nodes.
|
//loop over all edges and generate new set of nodes.
|
||||||
for(_NodeBasedDynamicGraph::NodeIterator u = 0; u < _nodeBasedGraph->GetNumberOfNodes(); ++u ) {
|
for(
|
||||||
for(_NodeBasedDynamicGraph::EdgeIterator e1 = _nodeBasedGraph->BeginEdges(u); e1 < _nodeBasedGraph->EndEdges(u); ++e1) {
|
NodeIterator u = 0,
|
||||||
_NodeBasedDynamicGraph::NodeIterator v = _nodeBasedGraph->GetTarget(e1);
|
number_of_nodes = m_node_based_graph->GetNumberOfNodes();
|
||||||
|
u < number_of_nodes;
|
||||||
|
++u
|
||||||
|
) {
|
||||||
|
p.printIncrement();
|
||||||
|
for(
|
||||||
|
EdgeIterator e1 = m_node_based_graph->BeginEdges(u),
|
||||||
|
last_edge = m_node_based_graph->EndEdges(u);
|
||||||
|
e1 < last_edge;
|
||||||
|
++e1
|
||||||
|
) {
|
||||||
|
NodeIterator v = m_node_based_graph->GetTarget(e1);
|
||||||
|
|
||||||
if(_nodeBasedGraph->GetEdgeData(e1).type != SHRT_MAX) {
|
if(m_node_based_graph->GetEdgeData(e1).type != SHRT_MAX) {
|
||||||
assert(e1 != UINT_MAX);
|
BOOST_ASSERT_MSG(e1 != UINT_MAX, "edge id invalid");
|
||||||
assert(u != UINT_MAX);
|
BOOST_ASSERT_MSG(u != UINT_MAX, "souce node invalid");
|
||||||
assert(v != UINT_MAX);
|
BOOST_ASSERT_MSG(v != UINT_MAX, "target node invalid");
|
||||||
//edges that end on bollard nodes may actually be in two distinct components
|
//Note: edges that end on barrier nodes or on a turn restriction
|
||||||
InsertEdgeBasedNode(e1, u, v, (std::min(vectorOfComponentSizes[componentsIndex[u]], vectorOfComponentSizes[componentsIndex[v]]) < 1000) );
|
//may actually be in two distinct components. We choose the smallest
|
||||||
|
const unsigned size_of_component = std::min(
|
||||||
|
component_size_list[component_index_list[u]],
|
||||||
|
component_size_list[component_index_list[v]]
|
||||||
|
);
|
||||||
|
|
||||||
|
InsertEdgeBasedNode( e1, u, v, size_of_component < 1000 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<NodeID>().swap(vectorOfComponentSizes);
|
SimpleLogger().Write()
|
||||||
std::vector<NodeID>().swap(componentsIndex);
|
<< "Generated " << m_edge_based_node_list.size() << " nodes in " <<
|
||||||
|
"edge-expanded graph";
|
||||||
|
SimpleLogger().Write() <<
|
||||||
|
"generating edge-expanded edges";
|
||||||
|
|
||||||
|
std::vector<NodeID>().swap(component_size_list);
|
||||||
|
BOOST_ASSERT_MSG(
|
||||||
|
0 == component_size_list.capacity(),
|
||||||
|
"component size vector not deallocated"
|
||||||
|
);
|
||||||
|
std::vector<NodeID>().swap(component_index_list);
|
||||||
|
BOOST_ASSERT_MSG(
|
||||||
|
0 == component_index_list.capacity(),
|
||||||
|
"component index vector not deallocated"
|
||||||
|
);
|
||||||
std::vector<OriginalEdgeData> original_edge_data_vector;
|
std::vector<OriginalEdgeData> original_edge_data_vector;
|
||||||
original_edge_data_vector.reserve(10000);
|
original_edge_data_vector.reserve(10000);
|
||||||
|
|
||||||
//Loop over all turns and generate new set of edges.
|
//Loop over all turns and generate new set of edges.
|
||||||
//Three nested loop look super-linear, but we are dealing with a linear number of turns only.
|
//Three nested loop look super-linear, but we are dealing with a (kind of)
|
||||||
for(_NodeBasedDynamicGraph::NodeIterator u = 0; u < _nodeBasedGraph->GetNumberOfNodes(); ++u ) {
|
//linear number of turns only.
|
||||||
for(_NodeBasedDynamicGraph::EdgeIterator e1 = _nodeBasedGraph->BeginEdges(u); e1 < _nodeBasedGraph->EndEdges(u); ++e1) {
|
p.reinit(m_node_based_graph->GetNumberOfNodes());
|
||||||
++nodeBasedEdgeCounter;
|
for(
|
||||||
_NodeBasedDynamicGraph::NodeIterator v = _nodeBasedGraph->GetTarget(e1);
|
NodeIterator u = 0,
|
||||||
bool isBollardNode = (_barrierNodes.find(v) != _barrierNodes.end());
|
last_node = m_node_based_graph->GetNumberOfNodes();
|
||||||
//EdgeWeight heightPenalty = ComputeHeightPenalty(u, v);
|
u < last_node;
|
||||||
NodeID onlyToNode = CheckForEmanatingIsOnlyTurn(u, v);
|
++u
|
||||||
for(_NodeBasedDynamicGraph::EdgeIterator e2 = _nodeBasedGraph->BeginEdges(v); e2 < _nodeBasedGraph->EndEdges(v); ++e2) {
|
) {
|
||||||
const _NodeBasedDynamicGraph::NodeIterator w = _nodeBasedGraph->GetTarget(e2);
|
for(
|
||||||
|
EdgeIterator e1 = m_node_based_graph->BeginEdges(u),
|
||||||
if(onlyToNode != UINT_MAX && w != onlyToNode) { //We are at an only_-restriction but not at the right turn.
|
last_edge_u = m_node_based_graph->EndEdges(u);
|
||||||
++numberOfSkippedTurns;
|
e1 < last_edge_u;
|
||||||
|
++e1
|
||||||
|
) {
|
||||||
|
++node_based_edge_counter;
|
||||||
|
NodeIterator v = m_node_based_graph->GetTarget(e1);
|
||||||
|
bool is_barrier_node = (m_barrier_nodes.find(v) != m_barrier_nodes.end());
|
||||||
|
NodeID to_node_of_only_restriction = CheckForEmanatingIsOnlyTurn(u, v);
|
||||||
|
for(
|
||||||
|
EdgeIterator e2 = m_node_based_graph->BeginEdges(v),
|
||||||
|
last_edge_v = m_node_based_graph->EndEdges(v);
|
||||||
|
e2 < last_edge_v;
|
||||||
|
++e2
|
||||||
|
) {
|
||||||
|
const NodeIterator w = m_node_based_graph->GetTarget(e2);
|
||||||
|
if(
|
||||||
|
to_node_of_only_restriction != UINT_MAX &&
|
||||||
|
w != to_node_of_only_restriction
|
||||||
|
) {
|
||||||
|
//We are at an only_-restriction but not at the right turn.
|
||||||
|
++skipped_turns_counter;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(u == w && 1 != _nodeBasedGraph->GetOutDegree(v) ) {
|
if(u == w && 1 != m_node_based_graph->GetOutDegree(v) ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !isBollardNode ) { //only add an edge if turn is not a U-turn except it is the end of dead-end street.
|
if( !is_barrier_node ) {
|
||||||
if (!CheckIfTurnIsRestricted(u, v, w) || (onlyToNode != UINT_MAX && w == onlyToNode)) { //only add an edge if turn is not prohibited
|
//only add an edge if turn is not a U-turn except when it is
|
||||||
const _NodeBasedDynamicGraph::EdgeData edgeData1 = _nodeBasedGraph->GetEdgeData(e1);
|
//at the end of a dead-end street
|
||||||
const _NodeBasedDynamicGraph::EdgeData edgeData2 = _nodeBasedGraph->GetEdgeData(e2);
|
if (
|
||||||
assert(edgeData1.edgeBasedNodeID < _nodeBasedGraph->GetNumberOfEdges());
|
!CheckIfTurnIsRestricted(u, v, w) ||
|
||||||
assert(edgeData2.edgeBasedNodeID < _nodeBasedGraph->GetNumberOfEdges());
|
(to_node_of_only_restriction != UINT_MAX && w == to_node_of_only_restriction)
|
||||||
|
) { //only add an edge if turn is not prohibited
|
||||||
|
const EdgeData edge_data1 = m_node_based_graph->GetEdgeData(e1);
|
||||||
|
const EdgeData edge_data2 = m_node_based_graph->GetEdgeData(e2);
|
||||||
|
assert(edge_data1.edgeBasedNodeID < m_node_based_graph->GetNumberOfEdges());
|
||||||
|
assert(edge_data2.edgeBasedNodeID < m_node_based_graph->GetNumberOfEdges());
|
||||||
|
|
||||||
if(!edgeData1.forward || !edgeData2.forward) {
|
if(!edge_data1.forward || !edge_data2.forward) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned distance = edgeData1.distance;
|
unsigned distance = edge_data1.distance;
|
||||||
if(_trafficLights.find(v) != _trafficLights.end()) {
|
if(m_traffic_lights.find(v) != m_traffic_lights.end()) {
|
||||||
distance += speedProfile.trafficSignalPenalty;
|
distance += speed_profile.trafficSignalPenalty;
|
||||||
}
|
}
|
||||||
unsigned penalty = GetTurnPenalty(u, v, w, myLuaState);
|
const unsigned penalty =
|
||||||
|
GetTurnPenalty(u, v, w, lua_state);
|
||||||
TurnInstruction turnInstruction = AnalyzeTurn(u, v, w);
|
TurnInstruction turnInstruction = AnalyzeTurn(u, v, w);
|
||||||
if(turnInstruction == TurnInstructions.UTurn)
|
if(turnInstruction == TurnInstructions.UTurn){
|
||||||
distance += speedProfile.uTurnPenalty;
|
distance += speed_profile.uTurnPenalty;
|
||||||
// if(!edgeData1.isAccessRestricted && edgeData2.isAccessRestricted) {
|
}
|
||||||
// distance += TurnInstructions.AccessRestrictionPenalty;
|
|
||||||
// turnInstruction |= TurnInstructions.AccessRestrictionFlag;
|
|
||||||
// }
|
|
||||||
distance += penalty;
|
distance += penalty;
|
||||||
|
|
||||||
|
assert(edge_data1.edgeBasedNodeID != edge_data2.edgeBasedNodeID);
|
||||||
//distance += heightPenalty;
|
original_edge_data_vector.push_back(
|
||||||
//distance += ComputeTurnPenalty(u, v, w);
|
OriginalEdgeData(
|
||||||
assert(edgeData1.edgeBasedNodeID != edgeData2.edgeBasedNodeID);
|
v,
|
||||||
OriginalEdgeData oed(v,edgeData2.nameID, turnInstruction);
|
edge_data2.nameID,
|
||||||
original_edge_data_vector.push_back(oed);
|
turnInstruction
|
||||||
++numberOfOriginalEdges;
|
)
|
||||||
|
);
|
||||||
|
++original_edges_counter;
|
||||||
|
|
||||||
if(original_edge_data_vector.size() > 100000) {
|
if(original_edge_data_vector.size() > 100000) {
|
||||||
originalEdgeDataOutFile.write((char*)&(original_edge_data_vector[0]), original_edge_data_vector.size()*sizeof(OriginalEdgeData));
|
edge_data_file.write(
|
||||||
|
(char*)&(original_edge_data_vector[0]),
|
||||||
|
original_edge_data_vector.size()*sizeof(OriginalEdgeData)
|
||||||
|
);
|
||||||
original_edge_data_vector.clear();
|
original_edge_data_vector.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
EdgeBasedEdge newEdge(edgeData1.edgeBasedNodeID, edgeData2.edgeBasedNodeID, edgeBasedEdges.size(), distance, true, false );
|
m_edge_based_edge_list.push_back(
|
||||||
edgeBasedEdges.push_back(newEdge);
|
EdgeBasedEdge(
|
||||||
|
edge_data1.edgeBasedNodeID,
|
||||||
|
edge_data2.edgeBasedNodeID,
|
||||||
|
m_edge_based_edge_list.size(),
|
||||||
|
distance,
|
||||||
|
true,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
++numberOfSkippedTurns;
|
++skipped_turns_counter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p.printIncrement();
|
p.printIncrement();
|
||||||
}
|
}
|
||||||
originalEdgeDataOutFile.write((char*)&(original_edge_data_vector[0]), original_edge_data_vector.size()*sizeof(OriginalEdgeData));
|
edge_data_file.write(
|
||||||
originalEdgeDataOutFile.seekp(std::ios::beg);
|
(char*)&(original_edge_data_vector[0]),
|
||||||
originalEdgeDataOutFile.write((char*)&numberOfOriginalEdges, sizeof(unsigned));
|
original_edge_data_vector.size()*sizeof(OriginalEdgeData)
|
||||||
originalEdgeDataOutFile.close();
|
);
|
||||||
|
edge_data_file.seekp(std::ios::beg);
|
||||||
|
edge_data_file.write(
|
||||||
|
(char*)&original_edges_counter,
|
||||||
|
sizeof(unsigned)
|
||||||
|
);
|
||||||
|
edge_data_file.close();
|
||||||
|
|
||||||
// SimpleLogger().Write() <<"Sorting edge-based Nodes";
|
SimpleLogger().Write() <<
|
||||||
// std::sort(edgeBasedNodes.begin(), edgeBasedNodes.end();
|
"Generated " << m_edge_based_node_list.size() << " edge based nodes";
|
||||||
// SimpleLogger().Write() <<"Removing duplicate nodes (if any)";
|
SimpleLogger().Write() <<
|
||||||
// edgeBasedNodes.erase( std::unique(edgeBasedNodes.begin(), edgeBasedNodes.end()), edgeBasedNodes.end() );
|
"Node-based graph contains " << node_based_edge_counter << " edges";
|
||||||
// SimpleLogger().Write() <<"Applying vector self-swap trick to free up memory";
|
SimpleLogger().Write() <<
|
||||||
// SimpleLogger().Write() <<"size: " << edgeBasedNodes.size() << ", cap: " << edgeBasedNodes.capacity();
|
"Edge-expanded graph ...";
|
||||||
// std::vector<EdgeBasedNode>(edgeBasedNodes).swap(edgeBasedNodes);
|
SimpleLogger().Write() <<
|
||||||
// SimpleLogger().Write() <<"size: " << edgeBasedNodes.size() << ", cap: " << edgeBasedNodes.capacity();
|
" contains " << m_edge_based_edge_list.size() << " edges";
|
||||||
SimpleLogger().Write() <<"Node-based graph contains " << nodeBasedEdgeCounter << " edges";
|
SimpleLogger().Write() <<
|
||||||
SimpleLogger().Write() <<"Edge-based graph contains " << edgeBasedEdges.size() << " edges";
|
" skips " << skipped_turns_counter << " turns, "
|
||||||
// SimpleLogger().Write() << "Edge-based graph contains " << edgeBasedEdges.size() << " edges, blowup is " << 2*((double)edgeBasedEdges.size()/(double)nodeBasedEdgeCounter;
|
"defined by " << m_turn_restrictions_count << " restrictions";
|
||||||
SimpleLogger().Write() <<"Edge-based graph skipped " << numberOfSkippedTurns << " turns, defined by " << numberOfTurnRestrictions << " restrictions.";
|
|
||||||
SimpleLogger().Write() <<"Generated " << edgeBasedNodes.size() << " edge based nodes";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int EdgeBasedGraphFactory::GetTurnPenalty(
|
int EdgeBasedGraphFactory::GetTurnPenalty(
|
||||||
const NodeID u,
|
const NodeID u,
|
||||||
const NodeID v,
|
const NodeID v,
|
||||||
const NodeID w,
|
const NodeID w,
|
||||||
lua_State *myLuaState
|
lua_State *lua_state
|
||||||
) const {
|
) const {
|
||||||
const double angle = GetAngleBetweenTwoEdges(
|
const double angle = GetAngleBetweenThreeFixedPointCoordinates (
|
||||||
inputNodeInfoList[u],
|
m_node_info_list[u],
|
||||||
inputNodeInfoList[v],
|
m_node_info_list[v],
|
||||||
inputNodeInfoList[w]
|
m_node_info_list[w]
|
||||||
);
|
);
|
||||||
|
|
||||||
if( speedProfile.has_turn_penalty_function ) {
|
if( speed_profile.has_turn_penalty_function ) {
|
||||||
try {
|
try {
|
||||||
//call lua profile to compute turn penalty
|
//call lua profile to compute turn penalty
|
||||||
return luabind::call_function<int>(
|
return luabind::call_function<int>(
|
||||||
myLuaState,
|
lua_state,
|
||||||
"turn_function",
|
"turn_function",
|
||||||
180.-angle
|
180.-angle
|
||||||
);
|
);
|
||||||
@ -381,17 +507,15 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(
|
|||||||
const NodeID v,
|
const NodeID v,
|
||||||
const NodeID w
|
const NodeID w
|
||||||
) const {
|
) const {
|
||||||
const double angle = GetAngleBetweenTwoEdges(inputNodeInfoList[u], inputNodeInfoList[v], inputNodeInfoList[w]);
|
|
||||||
|
|
||||||
if(u == w) {
|
if(u == w) {
|
||||||
return TurnInstructions.UTurn;
|
return TurnInstructions.UTurn;
|
||||||
}
|
}
|
||||||
|
|
||||||
_NodeBasedDynamicGraph::EdgeIterator edge1 = _nodeBasedGraph->FindEdge(u, v);
|
EdgeIterator edge1 = m_node_based_graph->FindEdge(u, v);
|
||||||
_NodeBasedDynamicGraph::EdgeIterator edge2 = _nodeBasedGraph->FindEdge(v, w);
|
EdgeIterator edge2 = m_node_based_graph->FindEdge(v, w);
|
||||||
|
|
||||||
_NodeBasedDynamicGraph::EdgeData & data1 = _nodeBasedGraph->GetEdgeData(edge1);
|
EdgeData & data1 = m_node_based_graph->GetEdgeData(edge1);
|
||||||
_NodeBasedDynamicGraph::EdgeData & data2 = _nodeBasedGraph->GetEdgeData(edge2);
|
EdgeData & data2 = m_node_based_graph->GetEdgeData(edge2);
|
||||||
|
|
||||||
if(!data1.contraFlow && data2.contraFlow) {
|
if(!data1.contraFlow && data2.contraFlow) {
|
||||||
return TurnInstructions.EnterAgainstAllowedDirection;
|
return TurnInstructions.EnterAgainstAllowedDirection;
|
||||||
@ -403,7 +527,7 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(
|
|||||||
//roundabouts need to be handled explicitely
|
//roundabouts need to be handled explicitely
|
||||||
if(data1.roundabout && data2.roundabout) {
|
if(data1.roundabout && data2.roundabout) {
|
||||||
//Is a turn possible? If yes, we stay on the roundabout!
|
//Is a turn possible? If yes, we stay on the roundabout!
|
||||||
if( 1 == (_nodeBasedGraph->EndEdges(v) - _nodeBasedGraph->BeginEdges(v)) ) {
|
if( 1 == m_node_based_graph->GetOutDegree(v) ) {
|
||||||
//No turn possible.
|
//No turn possible.
|
||||||
return TurnInstructions.NoTurn;
|
return TurnInstructions.NoTurn;
|
||||||
}
|
}
|
||||||
@ -421,31 +545,27 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//If street names stay the same and if we are certain that it is not a roundabout, we skip it.
|
//If street names stay the same and if we are certain that it is not a
|
||||||
if( (data1.nameID == data2.nameID) && (0 != data1.nameID)) {
|
//a segment of a roundabout, we skip it.
|
||||||
|
if( data1.nameID == data2.nameID ) {
|
||||||
|
//TODO: Here we should also do a small graph exploration to check for
|
||||||
|
// more complex situations
|
||||||
|
if( 0 != data1.nameID ) {
|
||||||
|
return TurnInstructions.NoTurn;
|
||||||
|
} else if (m_node_based_graph->GetOutDegree(v) <= 2) {
|
||||||
return TurnInstructions.NoTurn;
|
return TurnInstructions.NoTurn;
|
||||||
}
|
}
|
||||||
if( (data1.nameID == data2.nameID) && (0 == data1.nameID) && (_nodeBasedGraph->GetOutDegree(v) <= 2) ) {
|
|
||||||
return TurnInstructions.NoTurn;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const double angle = GetAngleBetweenThreeFixedPointCoordinates (
|
||||||
|
m_node_info_list[u],
|
||||||
|
m_node_info_list[v],
|
||||||
|
m_node_info_list[w]
|
||||||
|
);
|
||||||
|
|
||||||
return TurnInstructions.GetTurnDirectionOfInstruction(angle);
|
return TurnInstructions.GetTurnDirectionOfInstruction(angle);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned EdgeBasedGraphFactory::GetNumberOfNodes() const {
|
unsigned EdgeBasedGraphFactory::GetNumberOfNodes() const {
|
||||||
return _nodeBasedGraph->GetNumberOfEdges();
|
return m_node_based_graph->GetNumberOfEdges();
|
||||||
}
|
|
||||||
|
|
||||||
/* Get angle of line segment (A,C)->(C,B), atan2 magic, formerly cosine theorem*/
|
|
||||||
template<class CoordinateT>
|
|
||||||
double EdgeBasedGraphFactory::GetAngleBetweenTwoEdges(const CoordinateT& A, const CoordinateT& C, const CoordinateT& B) const {
|
|
||||||
const double v1x = (A.lon - C.lon)/COORDINATE_PRECISION;
|
|
||||||
const double v1y = lat2y(A.lat/COORDINATE_PRECISION) - lat2y(C.lat/COORDINATE_PRECISION);
|
|
||||||
const double v2x = (B.lon - C.lon)/COORDINATE_PRECISION;
|
|
||||||
const double v2y = lat2y(B.lat/COORDINATE_PRECISION) - lat2y(C.lat/COORDINATE_PRECISION);
|
|
||||||
|
|
||||||
double angle = (atan2(v2y,v2x) - atan2(v1y,v1x) )*180/M_PI;
|
|
||||||
while(angle < 0)
|
|
||||||
angle += 360;
|
|
||||||
return angle;
|
|
||||||
}
|
}
|
||||||
|
@ -18,9 +18,7 @@
|
|||||||
or see http://www.gnu.org/licenses/agpl.txt.
|
or see http://www.gnu.org/licenses/agpl.txt.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
// This class constructs the edge-expanded routing graph
|
||||||
* This class constructs the edge base representation of a graph from a given node based edge list
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef EDGEBASEDGRAPHFACTORY_H_
|
#ifndef EDGEBASEDGRAPHFACTORY_H_
|
||||||
#define EDGEBASEDGRAPHFACTORY_H_
|
#define EDGEBASEDGRAPHFACTORY_H_
|
||||||
@ -31,15 +29,12 @@
|
|||||||
#include "../Extractor/ExtractorStructs.h"
|
#include "../Extractor/ExtractorStructs.h"
|
||||||
#include "../DataStructures/HashTable.h"
|
#include "../DataStructures/HashTable.h"
|
||||||
#include "../DataStructures/ImportEdge.h"
|
#include "../DataStructures/ImportEdge.h"
|
||||||
#include "../DataStructures/MercatorUtil.h"
|
|
||||||
#include "../DataStructures/QueryEdge.h"
|
#include "../DataStructures/QueryEdge.h"
|
||||||
#include "../DataStructures/Percent.h"
|
#include "../DataStructures/Percent.h"
|
||||||
#include "../DataStructures/TurnInstructions.h"
|
#include "../DataStructures/TurnInstructions.h"
|
||||||
#include "../Util/LuaUtil.h"
|
#include "../Util/LuaUtil.h"
|
||||||
#include "../Util/SimpleLogger.h"
|
#include "../Util/SimpleLogger.h"
|
||||||
|
|
||||||
#include <stxxl.h>
|
|
||||||
|
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
#include <boost/make_shared.hpp>
|
#include <boost/make_shared.hpp>
|
||||||
#include <boost/noncopyable.hpp>
|
#include <boost/noncopyable.hpp>
|
||||||
@ -47,9 +42,8 @@
|
|||||||
#include <boost/unordered_map.hpp>
|
#include <boost/unordered_map.hpp>
|
||||||
#include <boost/unordered_set.hpp>
|
#include <boost/unordered_set.hpp>
|
||||||
|
|
||||||
#include <cstdlib>
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <fstream>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -67,6 +61,7 @@ public:
|
|||||||
weight(UINT_MAX >> 1),
|
weight(UINT_MAX >> 1),
|
||||||
ignoreInGrid(false)
|
ignoreInGrid(false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
bool operator<(const EdgeBasedNode & other) const {
|
bool operator<(const EdgeBasedNode & other) const {
|
||||||
return other.id < id;
|
return other.id < id;
|
||||||
}
|
}
|
||||||
@ -100,33 +95,47 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct SpeedProfileProperties{
|
struct SpeedProfileProperties{
|
||||||
SpeedProfileProperties() : trafficSignalPenalty(0), uTurnPenalty(0), has_turn_penalty_function(false) {}
|
SpeedProfileProperties() :
|
||||||
|
trafficSignalPenalty(0),
|
||||||
|
uTurnPenalty(0),
|
||||||
|
has_turn_penalty_function(false)
|
||||||
|
{ }
|
||||||
|
|
||||||
int trafficSignalPenalty;
|
int trafficSignalPenalty;
|
||||||
int uTurnPenalty;
|
int uTurnPenalty;
|
||||||
bool has_turn_penalty_function;
|
bool has_turn_penalty_function;
|
||||||
} speedProfile;
|
} speed_profile;
|
||||||
|
|
||||||
explicit EdgeBasedGraphFactory(
|
explicit EdgeBasedGraphFactory(
|
||||||
int nodes,
|
int number_of_nodes,
|
||||||
std::vector<ImportEdge> & inputEdges,
|
std::vector<ImportEdge> & input_edge_list,
|
||||||
std::vector<NodeID> & _bollardNodes,
|
std::vector<NodeID> & barrier_node_list,
|
||||||
std::vector<NodeID> & trafficLights,
|
std::vector<NodeID> & traffic_light_node_list,
|
||||||
std::vector<TurnRestriction> & inputRestrictions,
|
std::vector<TurnRestriction> & input_restrictions_list,
|
||||||
std::vector<NodeInfo> & nI,
|
std::vector<NodeInfo> & m_node_info_list,
|
||||||
SpeedProfileProperties speedProfile
|
SpeedProfileProperties speed_profile
|
||||||
);
|
);
|
||||||
|
|
||||||
void Run(const char * originalEdgeDataFilename, lua_State *myLuaState);
|
void Run(const char * originalEdgeDataFilename, lua_State *myLuaState);
|
||||||
void GetEdgeBasedEdges( DeallocatingVector< EdgeBasedEdge >& edges );
|
void GetEdgeBasedEdges( DeallocatingVector< EdgeBasedEdge >& edges );
|
||||||
void GetEdgeBasedNodes( std::vector< EdgeBasedNode> & nodes);
|
void GetEdgeBasedNodes( std::vector< EdgeBasedNode> & nodes);
|
||||||
void GetOriginalEdgeData( std::vector<OriginalEdgeData> & originalEdgeData);
|
void GetOriginalEdgeData( std::vector<OriginalEdgeData> & originalEdgeData);
|
||||||
TurnInstruction AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w) const;
|
TurnInstruction AnalyzeTurn(
|
||||||
int GetTurnPenalty(const NodeID u, const NodeID v, const NodeID w, lua_State *myLuaState) const;
|
const NodeID u,
|
||||||
|
const NodeID v,
|
||||||
|
const NodeID w
|
||||||
|
) const;
|
||||||
|
int GetTurnPenalty(
|
||||||
|
const NodeID u,
|
||||||
|
const NodeID v,
|
||||||
|
const NodeID w,
|
||||||
|
lua_State *myLuaState
|
||||||
|
) const;
|
||||||
|
|
||||||
unsigned GetNumberOfNodes() const;
|
unsigned GetNumberOfNodes() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct _NodeBasedEdgeData {
|
struct NodeBasedEdgeData {
|
||||||
int distance;
|
int distance;
|
||||||
unsigned edgeBasedNodeID;
|
unsigned edgeBasedNodeID;
|
||||||
unsigned nameID;
|
unsigned nameID;
|
||||||
@ -151,35 +160,44 @@ private:
|
|||||||
|
|
||||||
unsigned m_turn_restrictions_count;
|
unsigned m_turn_restrictions_count;
|
||||||
|
|
||||||
typedef DynamicGraph< _NodeBasedEdgeData > _NodeBasedDynamicGraph;
|
typedef DynamicGraph<NodeBasedEdgeData> NodeBasedDynamicGraph;
|
||||||
typedef _NodeBasedDynamicGraph::InputEdge _NodeBasedEdge;
|
typedef NodeBasedDynamicGraph::InputEdge NodeBasedEdge;
|
||||||
std::vector<NodeInfo> inputNodeInfoList;
|
typedef NodeBasedDynamicGraph::NodeIterator NodeIterator;
|
||||||
unsigned numberOfTurnRestrictions;
|
typedef NodeBasedDynamicGraph::EdgeIterator EdgeIterator;
|
||||||
|
typedef NodeBasedDynamicGraph::EdgeData EdgeData;
|
||||||
boost::shared_ptr<_NodeBasedDynamicGraph> _nodeBasedGraph;
|
|
||||||
boost::unordered_set<NodeID> _barrierNodes;
|
|
||||||
boost::unordered_set<NodeID> _trafficLights;
|
|
||||||
|
|
||||||
typedef std::pair<NodeID, NodeID> RestrictionSource;
|
typedef std::pair<NodeID, NodeID> RestrictionSource;
|
||||||
typedef std::pair<NodeID, bool> RestrictionTarget;
|
typedef std::pair<NodeID, bool> RestrictionTarget;
|
||||||
typedef std::vector<RestrictionTarget> EmanatingRestrictionsVector;
|
typedef std::vector<RestrictionTarget> EmanatingRestrictionsVector;
|
||||||
typedef boost::unordered_map<RestrictionSource, unsigned > RestrictionMap;
|
typedef boost::unordered_map<RestrictionSource, unsigned > RestrictionMap;
|
||||||
std::vector<EmanatingRestrictionsVector> _restrictionBucketVector;
|
|
||||||
RestrictionMap _restrictionMap;
|
|
||||||
|
|
||||||
DeallocatingVector<EdgeBasedEdge> edgeBasedEdges;
|
std::vector<NodeInfo> m_node_info_list;
|
||||||
std::vector<EdgeBasedNode> edgeBasedNodes;
|
std::vector<EmanatingRestrictionsVector> m_restriction_bucket_list;
|
||||||
|
std::vector<EdgeBasedNode> m_edge_based_node_list;
|
||||||
|
DeallocatingVector<EdgeBasedEdge> m_edge_based_edge_list;
|
||||||
|
|
||||||
|
boost::shared_ptr<NodeBasedDynamicGraph> m_node_based_graph;
|
||||||
|
boost::unordered_set<NodeID> m_barrier_nodes;
|
||||||
|
boost::unordered_set<NodeID> m_traffic_lights;
|
||||||
|
|
||||||
|
RestrictionMap m_restriction_map;
|
||||||
|
|
||||||
|
|
||||||
|
NodeID CheckForEmanatingIsOnlyTurn(
|
||||||
|
const NodeID u,
|
||||||
|
const NodeID v
|
||||||
|
) const;
|
||||||
|
|
||||||
|
bool CheckIfTurnIsRestricted(
|
||||||
|
const NodeID u,
|
||||||
|
const NodeID v,
|
||||||
|
const NodeID w
|
||||||
|
) const;
|
||||||
|
|
||||||
NodeID CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const;
|
|
||||||
bool CheckIfTurnIsRestricted(const NodeID u, const NodeID v, const NodeID w) const;
|
|
||||||
void InsertEdgeBasedNode(
|
void InsertEdgeBasedNode(
|
||||||
_NodeBasedDynamicGraph::EdgeIterator e1,
|
NodeBasedDynamicGraph::EdgeIterator e1,
|
||||||
_NodeBasedDynamicGraph::NodeIterator u,
|
NodeBasedDynamicGraph::NodeIterator u,
|
||||||
_NodeBasedDynamicGraph::NodeIterator v,
|
NodeBasedDynamicGraph::NodeIterator v,
|
||||||
bool belongsToTinyComponent);
|
bool belongsToTinyComponent);
|
||||||
template<class CoordinateT>
|
|
||||||
double GetAngleBetweenTwoEdges(const CoordinateT& A, const CoordinateT& C, const CoordinateT& B) const;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* EDGEBASEDGRAPHFACTORY_H_ */
|
#endif /* EDGEBASEDGRAPHFACTORY_H_ */
|
||||||
|
@ -18,8 +18,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
or see http://www.gnu.org/licenses/agpl.txt.
|
or see http://www.gnu.org/licenses/agpl.txt.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CONCURRENTQUEUE_H_INCLUDED
|
#ifndef CONCURRENTQUEUE_H_
|
||||||
#define CONCURRENTQUEUE_H_INCLUDED
|
#define CONCURRENTQUEUE_H_
|
||||||
|
|
||||||
|
#include "../typedefs.h"
|
||||||
|
|
||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
#include <boost/circular_buffer.hpp>
|
#include <boost/circular_buffer.hpp>
|
||||||
@ -27,57 +29,64 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
|||||||
#include <boost/thread/mutex.hpp>
|
#include <boost/thread/mutex.hpp>
|
||||||
#include <boost/thread/thread.hpp>
|
#include <boost/thread/thread.hpp>
|
||||||
|
|
||||||
#include "../typedefs.h"
|
|
||||||
|
|
||||||
template<typename Data>
|
template<typename Data>
|
||||||
class ConcurrentQueue {
|
class ConcurrentQueue {
|
||||||
|
|
||||||
typedef typename boost::circular_buffer<Data>::size_type size_t;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ConcurrentQueue(const size_t max_size) : internal_queue(max_size) { }
|
ConcurrentQueue(const size_t max_size) : m_internal_queue(max_size) { }
|
||||||
|
|
||||||
inline void push(Data const& data) {
|
inline void push(const Data & data) {
|
||||||
boost::mutex::scoped_lock lock(m_mutex);
|
boost::mutex::scoped_lock lock(m_mutex);
|
||||||
m_not_full.wait(lock, boost::bind(&ConcurrentQueue<Data>::is_not_full, this));
|
m_not_full.wait(
|
||||||
internal_queue.push_back(data);
|
lock,
|
||||||
|
boost::bind(&ConcurrentQueue<Data>::is_not_full, this)
|
||||||
|
);
|
||||||
|
m_internal_queue.push_back(data);
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
m_not_empty.notify_one();
|
m_not_empty.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool empty() const {
|
inline bool empty() const {
|
||||||
return internal_queue.empty();
|
return m_internal_queue.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void wait_and_pop(Data & popped_value) {
|
inline void wait_and_pop(Data & popped_value) {
|
||||||
boost::mutex::scoped_lock lock(m_mutex);
|
boost::mutex::scoped_lock lock(m_mutex);
|
||||||
m_not_empty.wait(lock, boost::bind(&ConcurrentQueue<Data>::is_not_empty, this));
|
m_not_empty.wait(
|
||||||
popped_value=internal_queue.front();
|
lock,
|
||||||
internal_queue.pop_front();
|
boost::bind(&ConcurrentQueue<Data>::is_not_empty, this)
|
||||||
|
);
|
||||||
|
popped_value = m_internal_queue.front();
|
||||||
|
m_internal_queue.pop_front();
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
m_not_full.notify_one();
|
m_not_full.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool try_pop(Data& popped_value) {
|
inline bool try_pop(Data& popped_value) {
|
||||||
boost::mutex::scoped_lock lock(m_mutex);
|
boost::mutex::scoped_lock lock(m_mutex);
|
||||||
if(internal_queue.empty()) {
|
if(m_internal_queue.empty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
popped_value=internal_queue.front();
|
popped_value=m_internal_queue.front();
|
||||||
internal_queue.pop_front();
|
m_internal_queue.pop_front();
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
m_not_full.notify_one();
|
m_not_full.notify_one();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
boost::circular_buffer<Data> internal_queue;
|
inline bool is_not_empty() const {
|
||||||
|
return !m_internal_queue.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool is_not_full() const {
|
||||||
|
return m_internal_queue.size() < m_internal_queue.capacity();
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::circular_buffer<Data> m_internal_queue;
|
||||||
boost::mutex m_mutex;
|
boost::mutex m_mutex;
|
||||||
boost::condition m_not_empty;
|
boost::condition m_not_empty;
|
||||||
boost::condition m_not_full;
|
boost::condition m_not_full;
|
||||||
|
|
||||||
inline bool is_not_empty() const { return internal_queue.size() > 0; }
|
|
||||||
inline bool is_not_full() const { return internal_queue.size() < internal_queue.capacity(); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //#ifndef CONCURRENTQUEUE_H_INCLUDED
|
#endif /* CONCURRENTQUEUE_H_ */
|
||||||
|
@ -21,6 +21,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
|||||||
#ifndef FIXED_POINT_COORDINATE_H_
|
#ifndef FIXED_POINT_COORDINATE_H_
|
||||||
#define FIXED_POINT_COORDINATE_H_
|
#define FIXED_POINT_COORDINATE_H_
|
||||||
|
|
||||||
|
#include "../DataStructures/MercatorUtil.h"
|
||||||
#include "../Util/StringUtil.h"
|
#include "../Util/StringUtil.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
@ -35,7 +36,7 @@ struct FixedPointCoordinate {
|
|||||||
int lat;
|
int lat;
|
||||||
int lon;
|
int lon;
|
||||||
FixedPointCoordinate () : lat(INT_MIN), lon(INT_MIN) {}
|
FixedPointCoordinate () : lat(INT_MIN), lon(INT_MIN) {}
|
||||||
explicit FixedPointCoordinate (int t, int n) : lat(t) , lon(n) {}
|
explicit FixedPointCoordinate (int lat, int lon) : lat(lat) , lon(lon) {}
|
||||||
|
|
||||||
void Reset() {
|
void Reset() {
|
||||||
lat = INT_MIN;
|
lat = INT_MIN;
|
||||||
@ -141,4 +142,22 @@ static inline void convertInternalReversedCoordinateToString(const FixedPointCoo
|
|||||||
output += " ";
|
output += " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Get angle of line segment (A,C)->(C,B), atan2 magic, formerly cosine theorem*/
|
||||||
|
template<class CoordinateT>
|
||||||
|
static inline double GetAngleBetweenThreeFixedPointCoordinates (
|
||||||
|
const CoordinateT & A,
|
||||||
|
const CoordinateT & C,
|
||||||
|
const CoordinateT & B
|
||||||
|
) {
|
||||||
|
const double v1x = (A.lon - C.lon)/COORDINATE_PRECISION;
|
||||||
|
const double v1y = lat2y(A.lat/COORDINATE_PRECISION) - lat2y(C.lat/COORDINATE_PRECISION);
|
||||||
|
const double v2x = (B.lon - C.lon)/COORDINATE_PRECISION;
|
||||||
|
const double v2y = lat2y(B.lat/COORDINATE_PRECISION) - lat2y(C.lat/COORDINATE_PRECISION);
|
||||||
|
|
||||||
|
double angle = (atan2(v2y,v2x) - atan2(v1y,v1x) )*180/M_PI;
|
||||||
|
while(angle < 0)
|
||||||
|
angle += 360;
|
||||||
|
return angle;
|
||||||
|
}
|
||||||
#endif /* FIXED_POINT_COORDINATE_H_ */
|
#endif /* FIXED_POINT_COORDINATE_H_ */
|
||||||
|
@ -18,16 +18,17 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
or see http://www.gnu.org/licenses/agpl.txt.
|
or see http://www.gnu.org/licenses/agpl.txt.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EDGE_H
|
#ifndef IMPORT_EDGE_H
|
||||||
#define EDGE_H
|
#define IMPORT_EDGE_H
|
||||||
|
|
||||||
|
|
||||||
#include "../Util/OSRMException.h"
|
#include "../Util/OSRMException.h"
|
||||||
#include <cassert>
|
#include "../typedefs.h"
|
||||||
|
|
||||||
|
#include <boost/assert.hpp>
|
||||||
|
|
||||||
class NodeBasedEdge {
|
class NodeBasedEdge {
|
||||||
public:
|
|
||||||
|
|
||||||
|
public:
|
||||||
bool operator< (const NodeBasedEdge& e) const {
|
bool operator< (const NodeBasedEdge& e) const {
|
||||||
if (source() == e.source()) {
|
if (source() == e.source()) {
|
||||||
if (target() == e.target()) {
|
if (target() == e.target()) {
|
||||||
@ -58,9 +59,9 @@ public:
|
|||||||
_target(t),
|
_target(t),
|
||||||
_name(n),
|
_name(n),
|
||||||
_weight(w),
|
_weight(w),
|
||||||
|
_type(ty),
|
||||||
forward(f),
|
forward(f),
|
||||||
backward(b),
|
backward(b),
|
||||||
_type(ty),
|
|
||||||
_roundabout(ra),
|
_roundabout(ra),
|
||||||
_ignoreInGrid(ig),
|
_ignoreInGrid(ig),
|
||||||
_accessRestricted(ar),
|
_accessRestricted(ar),
|
||||||
@ -75,8 +76,9 @@ public:
|
|||||||
NodeID source() const {return _source; }
|
NodeID source() const {return _source; }
|
||||||
NodeID name() const { return _name; }
|
NodeID name() const { return _name; }
|
||||||
EdgeWeight weight() const {return _weight; }
|
EdgeWeight weight() const {return _weight; }
|
||||||
|
short type() const {
|
||||||
short type() const { assert(_type >= 0); return _type; }
|
BOOST_ASSERT_MSG(_type >= 0, "type of ImportEdge invalid");
|
||||||
|
return _type; }
|
||||||
bool isBackward() const { return backward; }
|
bool isBackward() const { return backward; }
|
||||||
bool isForward() const { return forward; }
|
bool isForward() const { return forward; }
|
||||||
bool isLocatable() const { return _type != 14; }
|
bool isLocatable() const { return _type != 14; }
|
||||||
@ -85,28 +87,26 @@ public:
|
|||||||
bool isAccessRestricted() const { return _accessRestricted; }
|
bool isAccessRestricted() const { return _accessRestricted; }
|
||||||
bool isContraFlow() const { return _contraFlow; }
|
bool isContraFlow() const { return _contraFlow; }
|
||||||
|
|
||||||
|
//TODO: names need to be fixed.
|
||||||
NodeID _source;
|
NodeID _source;
|
||||||
NodeID _target;
|
NodeID _target;
|
||||||
NodeID _name;
|
NodeID _name;
|
||||||
EdgeWeight _weight;
|
EdgeWeight _weight;
|
||||||
bool forward;
|
|
||||||
bool backward;
|
|
||||||
short _type;
|
short _type;
|
||||||
bool _roundabout;
|
bool forward:1;
|
||||||
bool _ignoreInGrid;
|
bool backward:1;
|
||||||
bool _accessRestricted;
|
bool _roundabout:1;
|
||||||
bool _contraFlow;
|
bool _ignoreInGrid:1;
|
||||||
|
bool _accessRestricted:1;
|
||||||
|
bool _contraFlow:1;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/** Default constructor. target and weight are set to 0.*/
|
NodeBasedEdge() { }
|
||||||
NodeBasedEdge() :
|
|
||||||
_source(0), _target(0), _name(0), _weight(0), forward(0), backward(0), _type(0), _roundabout(false), _ignoreInGrid(false), _accessRestricted(false), _contraFlow(false) { assert(false); } //shall not be used.
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class EdgeBasedEdge {
|
class EdgeBasedEdge {
|
||||||
public:
|
|
||||||
|
|
||||||
|
public:
|
||||||
bool operator< (const EdgeBasedEdge& e) const {
|
bool operator< (const EdgeBasedEdge& e) const {
|
||||||
if (source() == e.source()) {
|
if (source() == e.source()) {
|
||||||
if (target() == e.target()) {
|
if (target() == e.target()) {
|
||||||
@ -141,7 +141,14 @@ public:
|
|||||||
m_backward(false)
|
m_backward(false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
explicit EdgeBasedEdge(const NodeID s, const NodeID t, const NodeID v, const EdgeWeight w, const bool f, const bool b) :
|
explicit EdgeBasedEdge(
|
||||||
|
const NodeID s,
|
||||||
|
const NodeID t,
|
||||||
|
const NodeID v,
|
||||||
|
const EdgeWeight w,
|
||||||
|
const bool f,
|
||||||
|
const bool b
|
||||||
|
) :
|
||||||
m_source(s),
|
m_source(s),
|
||||||
m_target(t),
|
m_target(t),
|
||||||
m_edgeID(v),
|
m_edgeID(v),
|
||||||
@ -156,6 +163,7 @@ public:
|
|||||||
NodeID id() const { return m_edgeID; }
|
NodeID id() const { return m_edgeID; }
|
||||||
bool isBackward() const { return m_backward; }
|
bool isBackward() const { return m_backward; }
|
||||||
bool isForward() const { return m_forward; }
|
bool isForward() const { return m_forward; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NodeID m_source;
|
NodeID m_source;
|
||||||
NodeID m_target;
|
NodeID m_target;
|
||||||
@ -167,4 +175,4 @@ private:
|
|||||||
|
|
||||||
typedef NodeBasedEdge ImportEdge;
|
typedef NodeBasedEdge ImportEdge;
|
||||||
|
|
||||||
#endif // EDGE_H
|
#endif /* IMPORT_EDGE_H */
|
||||||
|
@ -40,20 +40,23 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
|||||||
typedef EdgeBasedGraphFactory::EdgeBasedNode RTreeLeaf;
|
typedef EdgeBasedGraphFactory::EdgeBasedNode RTreeLeaf;
|
||||||
|
|
||||||
class NodeInformationHelpDesk : boost::noncopyable {
|
class NodeInformationHelpDesk : boost::noncopyable {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NodeInformationHelpDesk(
|
NodeInformationHelpDesk(
|
||||||
const std::string & ramIndexInput,
|
const std::string & ram_index_filename,
|
||||||
const std::string & fileIndexInput,
|
const std::string & mem_index_filename,
|
||||||
const std::string & nodes_filename,
|
const std::string & nodes_filename,
|
||||||
const std::string & edges_filename,
|
const std::string & edges_filename,
|
||||||
const unsigned number_of_nodes,
|
const unsigned m_number_of_nodes,
|
||||||
const unsigned check_sum
|
const unsigned m_check_sum
|
||||||
) : number_of_nodes(number_of_nodes), check_sum(check_sum)
|
) :
|
||||||
|
m_number_of_nodes(m_number_of_nodes),
|
||||||
|
m_check_sum(m_check_sum)
|
||||||
{
|
{
|
||||||
if ( ramIndexInput.empty() ) {
|
if ( ram_index_filename.empty() ) {
|
||||||
throw OSRMException("no ram index file name in server ini");
|
throw OSRMException("no ram index file name in server ini");
|
||||||
}
|
}
|
||||||
if ( fileIndexInput.empty() ) {
|
if ( mem_index_filename.empty() ) {
|
||||||
throw OSRMException("no mem index file name in server ini");
|
throw OSRMException("no mem index file name in server ini");
|
||||||
}
|
}
|
||||||
if ( nodes_filename.empty() ) {
|
if ( nodes_filename.empty() ) {
|
||||||
@ -63,47 +66,37 @@ public:
|
|||||||
throw OSRMException("no edges file name in server ini");
|
throw OSRMException("no edges file name in server ini");
|
||||||
}
|
}
|
||||||
|
|
||||||
read_only_rtree = new StaticRTree<RTreeLeaf>(
|
m_ro_rtree_ptr = new StaticRTree<RTreeLeaf>(
|
||||||
ramIndexInput,
|
ram_index_filename,
|
||||||
fileIndexInput
|
mem_index_filename
|
||||||
);
|
);
|
||||||
BOOST_ASSERT_MSG(
|
BOOST_ASSERT_MSG(
|
||||||
0 == coordinateVector.size(),
|
0 == m_coordinate_list.size(),
|
||||||
"Coordinate vector not empty"
|
"Coordinate vector not empty"
|
||||||
);
|
);
|
||||||
|
|
||||||
LoadNodesAndEdges(nodes_filename, edges_filename);
|
LoadNodesAndEdges(nodes_filename, edges_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Todo: Shared memory mechanism
|
|
||||||
~NodeInformationHelpDesk() {
|
~NodeInformationHelpDesk() {
|
||||||
delete read_only_rtree;
|
delete m_ro_rtree_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int getLatitudeOfNode(const unsigned id) const {
|
inline FixedPointCoordinate GetCoordinateOfNode(const unsigned id) const {
|
||||||
const NodeID node = origEdgeData_viaNode.at(id);
|
const NodeID node = m_via_node_list.at(id);
|
||||||
return coordinateVector.at(node).lat;
|
return m_coordinate_list.at(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int getLongitudeOfNode(const unsigned id) const {
|
inline unsigned GetNameIndexFromEdgeID(const unsigned id) const {
|
||||||
const NodeID node = origEdgeData_viaNode.at(id);
|
return m_name_ID_list.at(id);
|
||||||
return coordinateVector.at(node).lon;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned getNameIndexFromEdgeID(const unsigned id) const {
|
inline TurnInstruction GetTurnInstructionForEdgeID(const unsigned id) const {
|
||||||
return origEdgeData_nameID.at(id);
|
return m_turn_instruction_list.at(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline TurnInstruction getTurnInstructionFromEdgeID(const unsigned id) const {
|
inline NodeID GetNumberOfNodes() const {
|
||||||
return origEdgeData_turnInstruction.at(id);
|
return m_number_of_nodes;
|
||||||
}
|
|
||||||
|
|
||||||
inline NodeID getNumberOfNodes() const {
|
|
||||||
return number_of_nodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline NodeID getNumberOfNodes2() const {
|
|
||||||
return coordinateVector.size();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool FindNearestNodeCoordForLatLon(
|
inline bool FindNearestNodeCoordForLatLon(
|
||||||
@ -112,12 +105,12 @@ public:
|
|||||||
const unsigned zoom_level = 18
|
const unsigned zoom_level = 18
|
||||||
) const {
|
) const {
|
||||||
PhantomNode resulting_phantom_node;
|
PhantomNode resulting_phantom_node;
|
||||||
bool foundNode = FindPhantomNodeForCoordinate(
|
bool found_node = FindPhantomNodeForCoordinate(
|
||||||
input_coordinate,
|
input_coordinate,
|
||||||
resulting_phantom_node, zoom_level
|
resulting_phantom_node, zoom_level
|
||||||
);
|
);
|
||||||
result = resulting_phantom_node.location;
|
result = resulting_phantom_node.location;
|
||||||
return foundNode;
|
return found_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool FindPhantomNodeForCoordinate(
|
inline bool FindPhantomNodeForCoordinate(
|
||||||
@ -125,7 +118,7 @@ public:
|
|||||||
PhantomNode & resulting_phantom_node,
|
PhantomNode & resulting_phantom_node,
|
||||||
const unsigned zoom_level
|
const unsigned zoom_level
|
||||||
) const {
|
) const {
|
||||||
return read_only_rtree->FindPhantomNodeForCoordinate(
|
return m_ro_rtree_ptr->FindPhantomNodeForCoordinate(
|
||||||
input_coordinate,
|
input_coordinate,
|
||||||
resulting_phantom_node,
|
resulting_phantom_node,
|
||||||
zoom_level
|
zoom_level
|
||||||
@ -133,7 +126,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned GetCheckSum() const {
|
inline unsigned GetCheckSum() const {
|
||||||
return check_sum;
|
return m_check_sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -157,48 +150,63 @@ private:
|
|||||||
throw OSRMException("edges file is empty");
|
throw OSRMException("edges file is empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::filesystem::ifstream nodes_input_stream(nodes_file, std::ios::binary);
|
boost::filesystem::ifstream nodes_input_stream(
|
||||||
boost::filesystem::ifstream edges_input_stream(edges_file, std::ios::binary);
|
nodes_file,
|
||||||
|
std::ios::binary
|
||||||
|
);
|
||||||
|
|
||||||
SimpleLogger().Write(logDEBUG) << "Loading node data";
|
boost::filesystem::ifstream edges_input_stream(
|
||||||
NodeInfo b;
|
edges_file, std::ios::binary
|
||||||
|
);
|
||||||
|
|
||||||
|
SimpleLogger().Write(logDEBUG)
|
||||||
|
<< "Loading node data";
|
||||||
|
NodeInfo current_node;
|
||||||
while(!nodes_input_stream.eof()) {
|
while(!nodes_input_stream.eof()) {
|
||||||
nodes_input_stream.read((char *)&b, sizeof(NodeInfo));
|
nodes_input_stream.read((char *)¤t_node, sizeof(NodeInfo));
|
||||||
coordinateVector.push_back(FixedPointCoordinate(b.lat, b.lon));
|
m_coordinate_list.push_back(
|
||||||
|
FixedPointCoordinate(
|
||||||
|
current_node.lat,
|
||||||
|
current_node.lon
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
std::vector<FixedPointCoordinate>(coordinateVector).swap(coordinateVector);
|
std::vector<FixedPointCoordinate>(m_coordinate_list).swap(m_coordinate_list);
|
||||||
nodes_input_stream.close();
|
nodes_input_stream.close();
|
||||||
|
|
||||||
SimpleLogger().Write(logDEBUG) << "Loading edge data";
|
SimpleLogger().Write(logDEBUG)
|
||||||
unsigned numberOfOrigEdges(0);
|
<< "Loading edge data";
|
||||||
edges_input_stream.read((char*)&numberOfOrigEdges, sizeof(unsigned));
|
unsigned number_of_edges = 0;
|
||||||
origEdgeData_viaNode.resize(numberOfOrigEdges);
|
edges_input_stream.read((char*)&number_of_edges, sizeof(unsigned));
|
||||||
origEdgeData_nameID.resize(numberOfOrigEdges);
|
m_via_node_list.resize(number_of_edges);
|
||||||
origEdgeData_turnInstruction.resize(numberOfOrigEdges);
|
m_name_ID_list.resize(number_of_edges);
|
||||||
|
m_turn_instruction_list.resize(number_of_edges);
|
||||||
|
|
||||||
OriginalEdgeData deserialized_originalEdgeData;
|
OriginalEdgeData current_edge_data;
|
||||||
for(unsigned i = 0; i < numberOfOrigEdges; ++i) {
|
for(unsigned i = 0; i < number_of_edges; ++i) {
|
||||||
edges_input_stream.read(
|
edges_input_stream.read(
|
||||||
(char*)&(deserialized_originalEdgeData),
|
(char*)&(current_edge_data),
|
||||||
sizeof(OriginalEdgeData)
|
sizeof(OriginalEdgeData)
|
||||||
);
|
);
|
||||||
origEdgeData_viaNode[i] = deserialized_originalEdgeData.viaNode;
|
m_via_node_list[i] = current_edge_data.viaNode;
|
||||||
origEdgeData_nameID[i] = deserialized_originalEdgeData.nameID;
|
m_name_ID_list[i] = current_edge_data.nameID;
|
||||||
origEdgeData_turnInstruction[i] = deserialized_originalEdgeData.turnInstruction;
|
m_turn_instruction_list[i] = current_edge_data.turnInstruction;
|
||||||
}
|
}
|
||||||
edges_input_stream.close();
|
edges_input_stream.close();
|
||||||
SimpleLogger().Write(logDEBUG) << "Loaded " << numberOfOrigEdges << " orig edges";
|
SimpleLogger().Write(logDEBUG)
|
||||||
SimpleLogger().Write(logDEBUG) << "Opening NN indices";
|
<< "Loaded " << number_of_edges << " orig edges";
|
||||||
|
SimpleLogger().Write(logDEBUG)
|
||||||
|
<< "Opening NN indices";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<FixedPointCoordinate> coordinateVector;
|
std::vector<FixedPointCoordinate> m_coordinate_list;
|
||||||
std::vector<NodeID> origEdgeData_viaNode;
|
std::vector<NodeID> m_via_node_list;
|
||||||
std::vector<unsigned> origEdgeData_nameID;
|
std::vector<unsigned> m_name_ID_list;
|
||||||
std::vector<TurnInstruction> origEdgeData_turnInstruction;
|
std::vector<TurnInstruction> m_turn_instruction_list;
|
||||||
|
|
||||||
StaticRTree<EdgeBasedGraphFactory::EdgeBasedNode> * read_only_rtree;
|
StaticRTree<EdgeBasedGraphFactory::EdgeBasedNode> * m_ro_rtree_ptr;
|
||||||
const unsigned number_of_nodes;
|
const unsigned m_number_of_nodes;
|
||||||
const unsigned check_sum;
|
const unsigned m_check_sum;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /*NODEINFORMATIONHELPDESK_H_*/
|
#endif /*NODEINFORMATIONHELPDESK_H_*/
|
||||||
|
@ -18,8 +18,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
or see http://www.gnu.org/licenses/agpl.txt.
|
or see http://www.gnu.org/licenses/agpl.txt.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef QUERYEDGE_H_
|
#ifndef QUERYEDGE_H_
|
||||||
#define QUERYEDGE_H_
|
#define QUERYEDGE_H_
|
||||||
|
|
||||||
|
@ -21,8 +21,12 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
|||||||
#ifndef RAWROUTEDATA_H_
|
#ifndef RAWROUTEDATA_H_
|
||||||
#define RAWROUTEDATA_H_
|
#define RAWROUTEDATA_H_
|
||||||
|
|
||||||
|
#include "../DataStructures/Coordinate.h"
|
||||||
|
#include "../DataStructures/PhantomNodes.h"
|
||||||
#include "../typedefs.h"
|
#include "../typedefs.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
struct _PathData {
|
struct _PathData {
|
||||||
_PathData(NodeID no, unsigned na, unsigned tu, unsigned dur) : node(no), nameID(na), durationOfSegment(dur), turnInstruction(tu) { }
|
_PathData(NodeID no, unsigned na, unsigned tu, unsigned dur) : node(no), nameID(na), durationOfSegment(dur), turnInstruction(tu) { }
|
||||||
NodeID node;
|
NodeID node;
|
@ -29,14 +29,14 @@ SearchEngine::SearchEngine(
|
|||||||
shortestPath(_queryData),
|
shortestPath(_queryData),
|
||||||
alternativePaths(_queryData)
|
alternativePaths(_queryData)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
SearchEngine::~SearchEngine() {}
|
SearchEngine::~SearchEngine() {}
|
||||||
|
|
||||||
void SearchEngine::GetCoordinatesForNodeID(
|
void SearchEngine::GetCoordinatesForNodeID(
|
||||||
NodeID id,
|
NodeID id,
|
||||||
FixedPointCoordinate& result
|
FixedPointCoordinate& result
|
||||||
) const {
|
) const {
|
||||||
result.lat = _queryData.nodeHelpDesk->getLatitudeOfNode(id);
|
result = _queryData.nodeHelpDesk->GetCoordinateOfNode(id);
|
||||||
result.lon = _queryData.nodeHelpDesk->getLongitudeOfNode(id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SearchEngine::FindPhantomNodeForCoordinate(
|
void SearchEngine::FindPhantomNodeForCoordinate(
|
||||||
@ -57,13 +57,16 @@ NodeID SearchEngine::GetNameIDForOriginDestinationNodeID(
|
|||||||
if(s == t) {
|
if(s == t) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
EdgeID e = _queryData.graph->FindEdge(s, t);
|
EdgeID e = _queryData.graph->FindEdge(s, t);
|
||||||
if(e == UINT_MAX) {
|
if(e == UINT_MAX) {
|
||||||
e = _queryData.graph->FindEdge( t, s );
|
e = _queryData.graph->FindEdge( t, s );
|
||||||
}
|
}
|
||||||
|
|
||||||
if(UINT_MAX == e) {
|
if(UINT_MAX == e) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(e != UINT_MAX);
|
assert(e != UINT_MAX);
|
||||||
const QueryEdge::EdgeData ed = _queryData.graph->GetEdgeData(e);
|
const QueryEdge::EdgeData ed = _queryData.graph->GetEdgeData(e);
|
||||||
return ed.id;
|
return ed.id;
|
||||||
@ -86,4 +89,3 @@ SearchEngineHeapPtr SearchEngineData::backwardHeap2;
|
|||||||
|
|
||||||
SearchEngineHeapPtr SearchEngineData::forwardHeap3;
|
SearchEngineHeapPtr SearchEngineData::forwardHeap3;
|
||||||
SearchEngineHeapPtr SearchEngineData::backwardHeap3;
|
SearchEngineHeapPtr SearchEngineData::backwardHeap3;
|
||||||
|
|
||||||
|
@ -22,12 +22,12 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
|||||||
|
|
||||||
void SearchEngineData::InitializeOrClearFirstThreadLocalStorage() {
|
void SearchEngineData::InitializeOrClearFirstThreadLocalStorage() {
|
||||||
if(!forwardHeap.get()) {
|
if(!forwardHeap.get()) {
|
||||||
forwardHeap.reset(new QueryHeap(nodeHelpDesk->getNumberOfNodes()));
|
forwardHeap.reset(new QueryHeap(nodeHelpDesk->GetNumberOfNodes()));
|
||||||
} else {
|
} else {
|
||||||
forwardHeap->Clear();
|
forwardHeap->Clear();
|
||||||
}
|
}
|
||||||
if(!backwardHeap.get()) {
|
if(!backwardHeap.get()) {
|
||||||
backwardHeap.reset(new QueryHeap(nodeHelpDesk->getNumberOfNodes()));
|
backwardHeap.reset(new QueryHeap(nodeHelpDesk->GetNumberOfNodes()));
|
||||||
} else {
|
} else {
|
||||||
backwardHeap->Clear();
|
backwardHeap->Clear();
|
||||||
}
|
}
|
||||||
@ -35,12 +35,12 @@ void SearchEngineData::InitializeOrClearFirstThreadLocalStorage() {
|
|||||||
|
|
||||||
void SearchEngineData::InitializeOrClearSecondThreadLocalStorage() {
|
void SearchEngineData::InitializeOrClearSecondThreadLocalStorage() {
|
||||||
if(!forwardHeap2.get()) {
|
if(!forwardHeap2.get()) {
|
||||||
forwardHeap2.reset(new QueryHeap(nodeHelpDesk->getNumberOfNodes()));
|
forwardHeap2.reset(new QueryHeap(nodeHelpDesk->GetNumberOfNodes()));
|
||||||
} else {
|
} else {
|
||||||
forwardHeap2->Clear();
|
forwardHeap2->Clear();
|
||||||
}
|
}
|
||||||
if(!backwardHeap2.get()) {
|
if(!backwardHeap2.get()) {
|
||||||
backwardHeap2.reset(new QueryHeap(nodeHelpDesk->getNumberOfNodes()));
|
backwardHeap2.reset(new QueryHeap(nodeHelpDesk->GetNumberOfNodes()));
|
||||||
} else {
|
} else {
|
||||||
backwardHeap2->Clear();
|
backwardHeap2->Clear();
|
||||||
}
|
}
|
||||||
@ -48,12 +48,12 @@ void SearchEngineData::InitializeOrClearSecondThreadLocalStorage() {
|
|||||||
|
|
||||||
void SearchEngineData::InitializeOrClearThirdThreadLocalStorage() {
|
void SearchEngineData::InitializeOrClearThirdThreadLocalStorage() {
|
||||||
if(!forwardHeap3.get()) {
|
if(!forwardHeap3.get()) {
|
||||||
forwardHeap3.reset(new QueryHeap(nodeHelpDesk->getNumberOfNodes()));
|
forwardHeap3.reset(new QueryHeap(nodeHelpDesk->GetNumberOfNodes()));
|
||||||
} else {
|
} else {
|
||||||
forwardHeap3->Clear();
|
forwardHeap3->Clear();
|
||||||
}
|
}
|
||||||
if(!backwardHeap3.get()) {
|
if(!backwardHeap3.get()) {
|
||||||
backwardHeap3.reset(new QueryHeap(nodeHelpDesk->getNumberOfNodes()));
|
backwardHeap3.reset(new QueryHeap(nodeHelpDesk->GetNumberOfNodes()));
|
||||||
} else {
|
} else {
|
||||||
backwardHeap3->Clear();
|
backwardHeap3->Clear();
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
|||||||
#ifndef STATICGRAPH_H_INCLUDED
|
#ifndef STATICGRAPH_H_INCLUDED
|
||||||
#define STATICGRAPH_H_INCLUDED
|
#define STATICGRAPH_H_INCLUDED
|
||||||
|
|
||||||
|
#include "../DataStructures/Percent.h"
|
||||||
#include "../Util/SimpleLogger.h"
|
#include "../Util/SimpleLogger.h"
|
||||||
#include "../typedefs.h"
|
#include "../typedefs.h"
|
||||||
|
|
||||||
|
@ -23,8 +23,9 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
|||||||
|
|
||||||
#include "../DataStructures/HashTable.h"
|
#include "../DataStructures/HashTable.h"
|
||||||
#include "../DataStructures/PhantomNodes.h"
|
#include "../DataStructures/PhantomNodes.h"
|
||||||
|
#include "../DataStructures/RawRouteData.h"
|
||||||
#include "../DataStructures/SearchEngine.h"
|
#include "../DataStructures/SearchEngine.h"
|
||||||
#include "../Plugins/RawRouteData.h"
|
#include "../Server/BasicDatastructures.h"
|
||||||
#include "../Util/StringUtil.h"
|
#include "../Util/StringUtil.h"
|
||||||
#include "../typedefs.h"
|
#include "../typedefs.h"
|
||||||
|
|
||||||
|
@ -72,9 +72,6 @@ void BaseParser::ParseNodeInLua(ImportNode& n, lua_State* localLuaState) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BaseParser::ParseWayInLua(ExtractionWay& w, lua_State* localLuaState) {
|
void BaseParser::ParseWayInLua(ExtractionWay& w, lua_State* localLuaState) {
|
||||||
if(2 > w.path.size()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
luabind::call_function<void>( localLuaState, "way_function", boost::ref(w) );
|
luabind::call_function<void>( localLuaState, "way_function", boost::ref(w) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +111,10 @@ void ExtractionContainers::PrepareData(const std::string & output_file_name, con
|
|||||||
restrictionsIT->restriction.toNode = wayStartAndEndEdgeIT->firstStart;
|
restrictionsIT->restriction.toNode = wayStartAndEndEdgeIT->firstStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(UINT_MAX != restrictionsIT->restriction.fromNode && UINT_MAX != restrictionsIT->restriction.toNode) {
|
if(
|
||||||
|
UINT_MAX != restrictionsIT->restriction.fromNode &&
|
||||||
|
UINT_MAX != restrictionsIT->restriction.toNode
|
||||||
|
) {
|
||||||
++usableRestrictionsCounter;
|
++usableRestrictionsCounter;
|
||||||
}
|
}
|
||||||
++restrictionsIT;
|
++restrictionsIT;
|
||||||
@ -123,8 +126,15 @@ void ExtractionContainers::PrepareData(const std::string & output_file_name, con
|
|||||||
restrictionsOutstream.open(restrictionsFileName.c_str(), std::ios::binary);
|
restrictionsOutstream.open(restrictionsFileName.c_str(), std::ios::binary);
|
||||||
restrictionsOutstream.write((char*)&uuid, sizeof(UUID));
|
restrictionsOutstream.write((char*)&uuid, sizeof(UUID));
|
||||||
restrictionsOutstream.write((char*)&usableRestrictionsCounter, sizeof(unsigned));
|
restrictionsOutstream.write((char*)&usableRestrictionsCounter, sizeof(unsigned));
|
||||||
for(restrictionsIT = restrictionsVector.begin(); restrictionsIT != restrictionsVector.end(); ++restrictionsIT) {
|
for(
|
||||||
if(UINT_MAX != restrictionsIT->restriction.fromNode && UINT_MAX != restrictionsIT->restriction.toNode) {
|
restrictionsIT = restrictionsVector.begin();
|
||||||
|
restrictionsIT != restrictionsVector.end();
|
||||||
|
++restrictionsIT
|
||||||
|
) {
|
||||||
|
if(
|
||||||
|
UINT_MAX != restrictionsIT->restriction.fromNode &&
|
||||||
|
UINT_MAX != restrictionsIT->restriction.toNode
|
||||||
|
) {
|
||||||
restrictionsOutstream.write((char *)&(restrictionsIT->restriction), sizeof(TurnRestriction));
|
restrictionsOutstream.write((char *)&(restrictionsIT->restriction), sizeof(TurnRestriction));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,7 @@ struct CmpWayByID : public std::binary_function<_WayIDStartAndEndEdge, _WayIDSta
|
|||||||
|
|
||||||
struct Cmp : public std::binary_function<NodeID, NodeID, bool> {
|
struct Cmp : public std::binary_function<NodeID, NodeID, bool> {
|
||||||
typedef NodeID value_type;
|
typedef NodeID value_type;
|
||||||
bool operator () (const NodeID & a, const NodeID & b) const {
|
bool operator () (const NodeID a, const NodeID b) const {
|
||||||
return a < b;
|
return a < b;
|
||||||
}
|
}
|
||||||
value_type max_value() {
|
value_type max_value() {
|
||||||
|
@ -178,9 +178,9 @@ inline void PBFParser::parseDenseNode(_ThreadData * threadData) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
const int keyValue = dense.keys_vals ( denseTagIndex+1 );
|
const int keyValue = dense.keys_vals ( denseTagIndex+1 );
|
||||||
const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(tagValue).data();
|
const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(tagValue);
|
||||||
const std::string & value = threadData->PBFprimitiveBlock.stringtable().s(keyValue).data();
|
const std::string & value = threadData->PBFprimitiveBlock.stringtable().s(keyValue);
|
||||||
extracted_nodes_vector[i].keyVals.insert(std::make_pair(key, value));
|
extracted_nodes_vector[i].keyVals.emplace(key, value);
|
||||||
denseTagIndex += 2;
|
denseTagIndex += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -191,7 +191,7 @@ inline void PBFParser::parseDenseNode(_ThreadData * threadData) {
|
|||||||
ParseNodeInLua( n, scriptingEnvironment.getLuaStateForThreadID(omp_get_thread_num()) );
|
ParseNodeInLua( n, scriptingEnvironment.getLuaStateForThreadID(omp_get_thread_num()) );
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_FOREACH(ImportNode &n, extracted_nodes_vector) {
|
BOOST_FOREACH(const ImportNode &n, extracted_nodes_vector) {
|
||||||
extractor_callbacks->nodeFunction(n);
|
extractor_callbacks->nodeFunction(n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -209,7 +209,8 @@ inline void PBFParser::parseRelation(_ThreadData * threadData) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const OSMPBF::PrimitiveGroup& group = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID );
|
const OSMPBF::PrimitiveGroup& group = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID );
|
||||||
for(int i = 0; i < group.relations_size(); ++i ) {
|
|
||||||
|
for(int i = 0, relation_size = group.relations_size(); i < relation_size; ++i ) {
|
||||||
std::string except_tag_string;
|
std::string except_tag_string;
|
||||||
const OSMPBF::Relation& inputRelation = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).relations(i);
|
const OSMPBF::Relation& inputRelation = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID ).relations(i);
|
||||||
bool isRestriction = false;
|
bool isRestriction = false;
|
||||||
@ -241,8 +242,12 @@ inline void PBFParser::parseRelation(_ThreadData * threadData) {
|
|||||||
if(isRestriction) {
|
if(isRestriction) {
|
||||||
int64_t lastRef = 0;
|
int64_t lastRef = 0;
|
||||||
_RawRestrictionContainer currentRestrictionContainer(isOnlyRestriction);
|
_RawRestrictionContainer currentRestrictionContainer(isOnlyRestriction);
|
||||||
for(int rolesIndex = 0; rolesIndex < inputRelation.roles_sid_size(); ++rolesIndex) {
|
for(
|
||||||
std::string role(threadData->PBFprimitiveBlock.stringtable().s( inputRelation.roles_sid( rolesIndex ) ).data());
|
int rolesIndex = 0, last_role = inputRelation.roles_sid_size();
|
||||||
|
rolesIndex < last_role;
|
||||||
|
++rolesIndex
|
||||||
|
) {
|
||||||
|
const std::string & role = threadData->PBFprimitiveBlock.stringtable().s( inputRelation.roles_sid( rolesIndex ) );
|
||||||
lastRef += inputRelation.memids(rolesIndex);
|
lastRef += inputRelation.memids(rolesIndex);
|
||||||
|
|
||||||
if(!("from" == role || "to" == role || "via" == role)) {
|
if(!("from" == role || "to" == role || "via" == role)) {
|
||||||
@ -280,7 +285,6 @@ inline void PBFParser::parseRelation(_ThreadData * threadData) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default: //should not happen
|
default: //should not happen
|
||||||
//cout << "unknown";
|
|
||||||
assert(false);
|
assert(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -309,17 +313,23 @@ inline void PBFParser::parseWay(_ThreadData * threadData) {
|
|||||||
for(int j = 0; j < number_of_keys; ++j) {
|
for(int j = 0; j < number_of_keys; ++j) {
|
||||||
const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(inputWay.keys(j));
|
const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(inputWay.keys(j));
|
||||||
const std::string & val = threadData->PBFprimitiveBlock.stringtable().s(inputWay.vals(j));
|
const std::string & val = threadData->PBFprimitiveBlock.stringtable().s(inputWay.vals(j));
|
||||||
parsed_way_vector[i].keyVals.insert(std::make_pair(key, val));
|
parsed_way_vector[i].keyVals.emplace(key, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma omp parallel for schedule ( guided )
|
#pragma omp parallel for schedule ( guided )
|
||||||
for(int i = 0; i < number_of_ways; ++i) {
|
for(int i = 0; i < number_of_ways; ++i) {
|
||||||
ExtractionWay & w = parsed_way_vector[i];
|
ExtractionWay & w = parsed_way_vector[i];
|
||||||
|
if(2 > w.path.size()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
ParseWayInLua( w, scriptingEnvironment.getLuaStateForThreadID( omp_get_thread_num()) );
|
ParseWayInLua( w, scriptingEnvironment.getLuaStateForThreadID( omp_get_thread_num()) );
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_FOREACH(ExtractionWay & w, parsed_way_vector) {
|
BOOST_FOREACH(ExtractionWay & w, parsed_way_vector) {
|
||||||
|
if(2 > w.path.size()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
extractor_callbacks->wayFunction(w);
|
extractor_callbacks->wayFunction(w);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -330,21 +340,21 @@ inline void PBFParser::loadGroup(_ThreadData * threadData) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
const OSMPBF::PrimitiveGroup& group = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID );
|
const OSMPBF::PrimitiveGroup& group = threadData->PBFprimitiveBlock.primitivegroup( threadData->currentGroupID );
|
||||||
threadData->entityTypeIndicator = 0;
|
threadData->entityTypeIndicator = TypeDummy;
|
||||||
if ( group.nodes_size() != 0 ) {
|
if ( 0 != group.nodes_size() ) {
|
||||||
threadData->entityTypeIndicator = TypeNode;
|
threadData->entityTypeIndicator = TypeNode;
|
||||||
}
|
}
|
||||||
if ( group.ways_size() != 0 ) {
|
if ( 0 != group.ways_size() ) {
|
||||||
threadData->entityTypeIndicator = TypeWay;
|
threadData->entityTypeIndicator = TypeWay;
|
||||||
}
|
}
|
||||||
if ( group.relations_size() != 0 ) {
|
if ( 0 != group.relations_size() ) {
|
||||||
threadData->entityTypeIndicator = TypeRelation;
|
threadData->entityTypeIndicator = TypeRelation;
|
||||||
}
|
}
|
||||||
if ( group.has_dense() ) {
|
if ( group.has_dense() ) {
|
||||||
threadData->entityTypeIndicator = TypeDenseNode;
|
threadData->entityTypeIndicator = TypeDenseNode;
|
||||||
assert( group.dense().id_size() != 0 );
|
assert( 0 != group.dense().id_size() );
|
||||||
}
|
}
|
||||||
assert( threadData->entityTypeIndicator != 0 );
|
assert( threadData->entityTypeIndicator != TypeDummy );
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void PBFParser::loadBlock(_ThreadData * threadData) {
|
inline void PBFParser::loadBlock(_ThreadData * threadData) {
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
class PBFParser : public BaseParser {
|
class PBFParser : public BaseParser {
|
||||||
|
|
||||||
enum EntityType {
|
enum EntityType {
|
||||||
|
TypeDummy = 0,
|
||||||
TypeNode = 1,
|
TypeNode = 1,
|
||||||
TypeWay = 2,
|
TypeWay = 2,
|
||||||
TypeRelation = 4,
|
TypeRelation = 4,
|
||||||
@ -53,7 +54,7 @@ class PBFParser : public BaseParser {
|
|||||||
struct _ThreadData {
|
struct _ThreadData {
|
||||||
int currentGroupID;
|
int currentGroupID;
|
||||||
int currentEntityID;
|
int currentEntityID;
|
||||||
short entityTypeIndicator;
|
EntityType entityTypeIndicator;
|
||||||
|
|
||||||
OSMPBF::BlobHeader PBFBlobHeader;
|
OSMPBF::BlobHeader PBFBlobHeader;
|
||||||
OSMPBF::Blob PBFBlob;
|
OSMPBF::Blob PBFBlob;
|
||||||
@ -75,15 +76,15 @@ private:
|
|||||||
inline void ReadData();
|
inline void ReadData();
|
||||||
inline void ParseData();
|
inline void ParseData();
|
||||||
inline void parseDenseNode (_ThreadData * threadData);
|
inline void parseDenseNode (_ThreadData * threadData);
|
||||||
inline void parseNode(_ThreadData * );
|
inline void parseNode (_ThreadData * threadData);
|
||||||
inline void parseRelation (_ThreadData * threadData);
|
inline void parseRelation (_ThreadData * threadData);
|
||||||
inline void parseWay (_ThreadData * threadData);
|
inline void parseWay (_ThreadData * threadData);
|
||||||
|
|
||||||
inline void loadGroup (_ThreadData * threadData);
|
inline void loadGroup (_ThreadData * threadData);
|
||||||
inline void loadBlock (_ThreadData * threadData);
|
inline void loadBlock (_ThreadData * threadData);
|
||||||
inline bool readPBFBlobHeader(std::fstream & stream, _ThreadData * threadData);
|
inline bool readPBFBlobHeader(std::fstream & stream, _ThreadData * threadData);
|
||||||
inline bool unpackZLIB(std::fstream &, _ThreadData * threadData);
|
inline bool unpackZLIB (std::fstream & stream, _ThreadData * threadData);
|
||||||
inline bool unpackLZMA(std::fstream &, _ThreadData * );
|
inline bool unpackLZMA (std::fstream & stream, _ThreadData * threadData);
|
||||||
inline bool readBlob (std::fstream & stream, _ThreadData * threadData);
|
inline bool readBlob (std::fstream & stream, _ThreadData * threadData);
|
||||||
inline bool readNextBlock (std::fstream & stream, _ThreadData * threadData);
|
inline bool readNextBlock (std::fstream & stream, _ThreadData * threadData);
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
|||||||
#include "../Plugins/NearestPlugin.h"
|
#include "../Plugins/NearestPlugin.h"
|
||||||
#include "../Plugins/TimestampPlugin.h"
|
#include "../Plugins/TimestampPlugin.h"
|
||||||
#include "../Plugins/ViaRoutePlugin.h"
|
#include "../Plugins/ViaRoutePlugin.h"
|
||||||
#include "../Plugins/RouteParameters.h"
|
#include "../Server/DataStructures/RouteParameters.h"
|
||||||
#include "../Util/IniFile.h"
|
#include "../Util/IniFile.h"
|
||||||
#include "../Util/InputFileUtil.h"
|
#include "../Util/InputFileUtil.h"
|
||||||
#include "../Util/OSRMException.h"
|
#include "../Util/OSRMException.h"
|
||||||
|
@ -21,9 +21,9 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
|||||||
#ifndef BASEPLUGIN_H_
|
#ifndef BASEPLUGIN_H_
|
||||||
#define BASEPLUGIN_H_
|
#define BASEPLUGIN_H_
|
||||||
|
|
||||||
#include "RouteParameters.h"
|
|
||||||
#include "../DataStructures/Coordinate.h"
|
#include "../DataStructures/Coordinate.h"
|
||||||
#include "../Server/BasicDatastructures.h"
|
#include "../Server/BasicDatastructures.h"
|
||||||
|
#include "../Server/DataStructures/RouteParameters.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -22,7 +22,6 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
|||||||
#define HELLOWORLDPLUGIN_H_
|
#define HELLOWORLDPLUGIN_H_
|
||||||
|
|
||||||
#include "BasePlugin.h"
|
#include "BasePlugin.h"
|
||||||
#include "RouteParameters.h"
|
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
@ -22,7 +22,6 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
|||||||
#define LOCATEPLUGIN_H_
|
#define LOCATEPLUGIN_H_
|
||||||
|
|
||||||
#include "BasePlugin.h"
|
#include "BasePlugin.h"
|
||||||
#include "RouteParameters.h"
|
|
||||||
#include "../DataStructures/NodeInformationHelpDesk.h"
|
#include "../DataStructures/NodeInformationHelpDesk.h"
|
||||||
#include "../Server/DataStructures/QueryObjectsStorage.h"
|
#include "../Server/DataStructures/QueryObjectsStorage.h"
|
||||||
#include "../Util/StringUtil.h"
|
#include "../Util/StringUtil.h"
|
||||||
|
@ -22,7 +22,6 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
|||||||
#define NearestPlugin_H_
|
#define NearestPlugin_H_
|
||||||
|
|
||||||
#include "BasePlugin.h"
|
#include "BasePlugin.h"
|
||||||
#include "RouteParameters.h"
|
|
||||||
|
|
||||||
#include "../DataStructures/NodeInformationHelpDesk.h"
|
#include "../DataStructures/NodeInformationHelpDesk.h"
|
||||||
#include "../Server/DataStructures/QueryObjectsStorage.h"
|
#include "../Server/DataStructures/QueryObjectsStorage.h"
|
||||||
|
@ -22,7 +22,6 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
|||||||
#define TIMESTAMPPLUGIN_H_
|
#define TIMESTAMPPLUGIN_H_
|
||||||
|
|
||||||
#include "BasePlugin.h"
|
#include "BasePlugin.h"
|
||||||
#include "RouteParameters.h"
|
|
||||||
|
|
||||||
class TimestampPlugin : public BasePlugin {
|
class TimestampPlugin : public BasePlugin {
|
||||||
public:
|
public:
|
||||||
|
@ -22,7 +22,6 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
|||||||
#define VIAROUTEPLUGIN_H_
|
#define VIAROUTEPLUGIN_H_
|
||||||
|
|
||||||
#include "BasePlugin.h"
|
#include "BasePlugin.h"
|
||||||
#include "RouteParameters.h"
|
|
||||||
|
|
||||||
#include "../Algorithms/ObjectToBase64.h"
|
#include "../Algorithms/ObjectToBase64.h"
|
||||||
#include "../DataStructures/HashTable.h"
|
#include "../DataStructures/HashTable.h"
|
||||||
@ -94,7 +93,7 @@ public:
|
|||||||
if(checksumOK && i < routeParameters.hints.size() && "" != routeParameters.hints[i]) {
|
if(checksumOK && i < routeParameters.hints.size() && "" != routeParameters.hints[i]) {
|
||||||
// SimpleLogger().Write() <<"Decoding hint: " << routeParameters.hints[i] << " for location index " << i;
|
// SimpleLogger().Write() <<"Decoding hint: " << routeParameters.hints[i] << " for location index " << i;
|
||||||
DecodeObjectFromBase64(routeParameters.hints[i], phantomNodeVector[i]);
|
DecodeObjectFromBase64(routeParameters.hints[i], phantomNodeVector[i]);
|
||||||
if(phantomNodeVector[i].isValid(nodeHelpDesk->getNumberOfNodes())) {
|
if(phantomNodeVector[i].isValid(nodeHelpDesk->GetNumberOfNodes())) {
|
||||||
// SimpleLogger().Write() << "Decoded hint " << i << " successfully";
|
// SimpleLogger().Write() << "Decoded hint " << i << " successfully";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
|||||||
#ifndef BASICROUTINGINTERFACE_H_
|
#ifndef BASICROUTINGINTERFACE_H_
|
||||||
#define BASICROUTINGINTERFACE_H_
|
#define BASICROUTINGINTERFACE_H_
|
||||||
|
|
||||||
#include "../Plugins/RawRouteData.h"
|
#include "../DataStructures/RawRouteData.h"
|
||||||
#include "../Util/ContainerUtils.h"
|
#include "../Util/ContainerUtils.h"
|
||||||
#include "../Util/SimpleLogger.h"
|
#include "../Util/SimpleLogger.h"
|
||||||
|
|
||||||
@ -148,7 +148,14 @@ public:
|
|||||||
recursionStack.push(std::make_pair(edge.first, middle));
|
recursionStack.push(std::make_pair(edge.first, middle));
|
||||||
} else {
|
} else {
|
||||||
assert(!ed.shortcut);
|
assert(!ed.shortcut);
|
||||||
unpackedPath.push_back(_PathData(ed.id, _queryData.nodeHelpDesk->getNameIndexFromEdgeID(ed.id), _queryData.nodeHelpDesk->getTurnInstructionFromEdgeID(ed.id), ed.distance) );
|
unpackedPath.push_back(
|
||||||
|
_PathData(
|
||||||
|
ed.id,
|
||||||
|
_queryData.nodeHelpDesk->GetNameIndexFromEdgeID(ed.id),
|
||||||
|
_queryData.nodeHelpDesk->GetTurnInstructionForEdgeID(ed.id),
|
||||||
|
ed.distance
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
|||||||
#ifndef ROUTE_PARAMETERS_H
|
#ifndef ROUTE_PARAMETERS_H
|
||||||
#define ROUTE_PARAMETERS_H
|
#define ROUTE_PARAMETERS_H
|
||||||
|
|
||||||
#include "../DataStructures/Coordinate.h"
|
#include "../../DataStructures/Coordinate.h"
|
||||||
#include "../DataStructures/HashTable.h"
|
#include "../../DataStructures/HashTable.h"
|
||||||
|
|
||||||
#include <boost/fusion/container/vector.hpp>
|
#include <boost/fusion/container/vector.hpp>
|
||||||
#include <boost/fusion/sequence/intrinsic.hpp>
|
#include <boost/fusion/sequence/intrinsic.hpp>
|
@ -23,8 +23,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
|||||||
|
|
||||||
#include "APIGrammar.h"
|
#include "APIGrammar.h"
|
||||||
#include "BasicDatastructures.h"
|
#include "BasicDatastructures.h"
|
||||||
|
#include "DataStructures/RouteParameters.h"
|
||||||
#include "../Library/OSRM.h"
|
#include "../Library/OSRM.h"
|
||||||
#include "../Plugins/RouteParameters.h"
|
|
||||||
#include "../Util/SimpleLogger.h"
|
#include "../Util/SimpleLogger.h"
|
||||||
#include "../Util/StringUtil.h"
|
#include "../Util/StringUtil.h"
|
||||||
#include "../typedefs.h"
|
#include "../typedefs.h"
|
||||||
@ -47,25 +47,35 @@ public:
|
|||||||
try {
|
try {
|
||||||
std::string request(req.uri);
|
std::string request(req.uri);
|
||||||
|
|
||||||
{ //This block logs the current request to std out. should be moved to a logging component
|
|
||||||
time_t ltime;
|
time_t ltime;
|
||||||
struct tm *Tm;
|
struct tm *Tm;
|
||||||
|
|
||||||
ltime=time(NULL);
|
ltime=time(NULL);
|
||||||
Tm=localtime(<ime);
|
Tm=localtime(<ime);
|
||||||
|
|
||||||
SimpleLogger().Write() << (Tm->tm_mday < 10 ? "0" : "" ) << Tm->tm_mday << "-" << (Tm->tm_mon+1 < 10 ? "0" : "" ) << (Tm->tm_mon+1) << "-" << 1900+Tm->tm_year << " " << (Tm->tm_hour < 10 ? "0" : "" ) << Tm->tm_hour << ":" << (Tm->tm_min < 10 ? "0" : "" ) << Tm->tm_min << ":" << (Tm->tm_sec < 10 ? "0" : "" ) << Tm->tm_sec << " " <<
|
SimpleLogger().Write() <<
|
||||||
req.endpoint.to_string() << " " << req.referrer << ( 0 == req.referrer.length() ? "- " :" ") << req.agent << ( 0 == req.agent.length() ? "- " :" ") << req.uri;
|
(Tm->tm_mday < 10 ? "0" : "" ) << Tm->tm_mday << "-" <<
|
||||||
}
|
(Tm->tm_mon+1 < 10 ? "0" : "" ) << (Tm->tm_mon+1) << "-" <<
|
||||||
|
1900+Tm->tm_year << " " << (Tm->tm_hour < 10 ? "0" : "" ) <<
|
||||||
|
Tm->tm_hour << ":" << (Tm->tm_min < 10 ? "0" : "" ) <<
|
||||||
|
Tm->tm_min << ":" << (Tm->tm_sec < 10 ? "0" : "" ) <<
|
||||||
|
Tm->tm_sec << " " << req.endpoint.to_string() << " " <<
|
||||||
|
req.referrer << ( 0 == req.referrer.length() ? "- " :" ") <<
|
||||||
|
req.agent << ( 0 == req.agent.length() ? "- " :" ") << req.uri;
|
||||||
|
|
||||||
RouteParameters routeParameters;
|
RouteParameters routeParameters;
|
||||||
APIGrammarParser apiParser(&routeParameters);
|
APIGrammarParser apiParser(&routeParameters);
|
||||||
|
|
||||||
std::string::iterator it = request.begin();
|
std::string::iterator it = request.begin();
|
||||||
bool result = boost::spirit::qi::parse(it, request.end(), apiParser);
|
const bool result = boost::spirit::qi::parse(
|
||||||
|
it,
|
||||||
|
request.end(),
|
||||||
|
apiParser
|
||||||
|
);
|
||||||
|
|
||||||
if ( !result || (it != request.end()) ) {
|
if ( !result || (it != request.end()) ) {
|
||||||
rep = http::Reply::stockReply(http::Reply::badRequest);
|
rep = http::Reply::stockReply(http::Reply::badRequest);
|
||||||
int position = std::distance(request.begin(), it);
|
const int position = std::distance(request.begin(), it);
|
||||||
std::string tmp_position_string;
|
std::string tmp_position_string;
|
||||||
intToString(position, tmp_position_string);
|
intToString(position, tmp_position_string);
|
||||||
rep.content += "Input seems to be malformed close to position ";
|
rep.content += "Input seems to be malformed close to position ";
|
||||||
@ -73,7 +83,7 @@ public:
|
|||||||
rep.content += request;
|
rep.content += request;
|
||||||
rep.content += tmp_position_string;
|
rep.content += tmp_position_string;
|
||||||
rep.content += "<br>";
|
rep.content += "<br>";
|
||||||
unsigned end = std::distance(request.begin(), it);
|
const unsigned end = std::distance(request.begin(), it);
|
||||||
for(unsigned i = 0; i < end; ++i) {
|
for(unsigned i = 0; i < end; ++i) {
|
||||||
rep.content += " ";
|
rep.content += " ";
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
|||||||
#include "../Util/InputFileUtil.h"
|
#include "../Util/InputFileUtil.h"
|
||||||
#include "../Util/OSRMException.h"
|
#include "../Util/OSRMException.h"
|
||||||
#include "../Util/SimpleLogger.h"
|
#include "../Util/SimpleLogger.h"
|
||||||
|
#include "../Util/UUID.h"
|
||||||
|
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@ -58,6 +59,16 @@ int main (int argc, char * argv[]) {
|
|||||||
SimpleLogger().Write() <<
|
SimpleLogger().Write() <<
|
||||||
"Using restrictions from file: " << argv[2];
|
"Using restrictions from file: " << argv[2];
|
||||||
std::ifstream restriction_ifstream(argv[2], std::ios::binary);
|
std::ifstream restriction_ifstream(argv[2], std::ios::binary);
|
||||||
|
const UUID uuid_orig;
|
||||||
|
UUID uuid_loaded;
|
||||||
|
restriction_ifstream.read((char *) &uuid_loaded, sizeof(UUID));
|
||||||
|
|
||||||
|
if( !uuid_loaded.TestGraphUtil(uuid_orig) ) {
|
||||||
|
SimpleLogger().Write(logWARNING) <<
|
||||||
|
argv[2] << " was prepared with a different build. "
|
||||||
|
"Reprocess to get rid of this warning.";
|
||||||
|
}
|
||||||
|
|
||||||
if(!restriction_ifstream.good()) {
|
if(!restriction_ifstream.good()) {
|
||||||
throw OSRMException("Could not access <osrm-restrictions> files");
|
throw OSRMException("Could not access <osrm-restrictions> files");
|
||||||
}
|
}
|
||||||
@ -92,6 +103,11 @@ int main (int argc, char * argv[]) {
|
|||||||
);
|
);
|
||||||
input_stream.close();
|
input_stream.close();
|
||||||
|
|
||||||
|
BOOST_ASSERT_MSG(
|
||||||
|
restrictions_vector.size() == usable_restriction_count,
|
||||||
|
"size of restrictions_vector changed"
|
||||||
|
);
|
||||||
|
|
||||||
SimpleLogger().Write() <<
|
SimpleLogger().Write() <<
|
||||||
restrictions_vector.size() << " restrictions, " <<
|
restrictions_vector.size() << " restrictions, " <<
|
||||||
bollard_node_IDs_vector.size() << " bollard nodes, " <<
|
bollard_node_IDs_vector.size() << " bollard nodes, " <<
|
||||||
|
@ -68,21 +68,21 @@ NodeID readBinaryOSRMGraphFromStream(
|
|||||||
|
|
||||||
if( !uuid_loaded.TestGraphUtil(uuid_orig) ) {
|
if( !uuid_loaded.TestGraphUtil(uuid_orig) ) {
|
||||||
SimpleLogger().Write(logWARNING) <<
|
SimpleLogger().Write(logWARNING) <<
|
||||||
".osrm was prepared with different build.\n"
|
".osrm was prepared with different build."
|
||||||
"Reprocess to get rid of this warning.";
|
"Reprocess to get rid of this warning.";
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeID n, source, target;
|
NodeID n, source, target;
|
||||||
EdgeID m;
|
EdgeID m;
|
||||||
short dir;// direction (0 = open, 1 = forward, 2+ = open)
|
short dir;// direction (0 = open, 1 = forward, 2+ = open)
|
||||||
ExternalNodeMap ext2IntNodeMap;
|
ExternalNodeMap ext_to_int_id_map;
|
||||||
in.read((char*)&n, sizeof(NodeID));
|
in.read((char*)&n, sizeof(NodeID));
|
||||||
SimpleLogger().Write() << "Importing n = " << n << " nodes ";
|
SimpleLogger().Write() << "Importing n = " << n << " nodes ";
|
||||||
_Node node;
|
_Node node;
|
||||||
for (NodeID i=0; i<n; ++i) {
|
for (NodeID i=0; i<n; ++i) {
|
||||||
in.read((char*)&node, sizeof(_Node));
|
in.read((char*)&node, sizeof(_Node));
|
||||||
int2ExtNodeMap->push_back(NodeInfo(node.lat, node.lon, node.id));
|
int2ExtNodeMap->push_back(NodeInfo(node.lat, node.lon, node.id));
|
||||||
ext2IntNodeMap.insert(std::make_pair(node.id, i));
|
ext_to_int_id_map.emplace(node.id, i);
|
||||||
if(node.bollard) {
|
if(node.bollard) {
|
||||||
bollardNodes.push_back(i);
|
bollardNodes.push_back(i);
|
||||||
}
|
}
|
||||||
@ -97,28 +97,29 @@ NodeID readBinaryOSRMGraphFromStream(
|
|||||||
|
|
||||||
in.read((char*)&m, sizeof(unsigned));
|
in.read((char*)&m, sizeof(unsigned));
|
||||||
SimpleLogger().Write() << " and " << m << " edges ";
|
SimpleLogger().Write() << " and " << m << " edges ";
|
||||||
for(unsigned i = 0; i < inputRestrictions.size(); ++i) {
|
// for(unsigned i = 0; i < inputRestrictions.size(); ++i) {
|
||||||
ExternalNodeMap::iterator intNodeID = ext2IntNodeMap.find(inputRestrictions[i].fromNode);
|
BOOST_FOREACH(TurnRestriction & current_restriction, inputRestrictions) {
|
||||||
if( intNodeID == ext2IntNodeMap.end()) {
|
ExternalNodeMap::iterator intNodeID = ext_to_int_id_map.find(current_restriction.fromNode);
|
||||||
|
if( intNodeID == ext_to_int_id_map.end()) {
|
||||||
SimpleLogger().Write(logDEBUG) << "Unmapped from Node of restriction";
|
SimpleLogger().Write(logDEBUG) << "Unmapped from Node of restriction";
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
}
|
}
|
||||||
inputRestrictions[i].fromNode = intNodeID->second;
|
current_restriction.fromNode = intNodeID->second;
|
||||||
|
|
||||||
intNodeID = ext2IntNodeMap.find(inputRestrictions[i].viaNode);
|
intNodeID = ext_to_int_id_map.find(current_restriction.viaNode);
|
||||||
if( intNodeID == ext2IntNodeMap.end()) {
|
if( intNodeID == ext_to_int_id_map.end()) {
|
||||||
SimpleLogger().Write(logDEBUG) << "Unmapped via node of restriction";
|
SimpleLogger().Write(logDEBUG) << "Unmapped via node of restriction";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
inputRestrictions[i].viaNode = intNodeID->second;
|
current_restriction.viaNode = intNodeID->second;
|
||||||
|
|
||||||
intNodeID = ext2IntNodeMap.find(inputRestrictions[i].toNode);
|
intNodeID = ext_to_int_id_map.find(current_restriction.toNode);
|
||||||
if( intNodeID == ext2IntNodeMap.end()) {
|
if( intNodeID == ext_to_int_id_map.end()) {
|
||||||
SimpleLogger().Write(logDEBUG) << "Unmapped to node of restriction";
|
SimpleLogger().Write(logDEBUG) << "Unmapped to node of restriction";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
inputRestrictions[i].toNode = intNodeID->second;
|
current_restriction.toNode = intNodeID->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
edgeList.reserve(m);
|
edgeList.reserve(m);
|
||||||
@ -153,8 +154,8 @@ NodeID readBinaryOSRMGraphFromStream(
|
|||||||
assert(type >= 0);
|
assert(type >= 0);
|
||||||
|
|
||||||
// translate the external NodeIDs to internal IDs
|
// translate the external NodeIDs to internal IDs
|
||||||
ExternalNodeMap::iterator intNodeID = ext2IntNodeMap.find(source);
|
ExternalNodeMap::iterator intNodeID = ext_to_int_id_map.find(source);
|
||||||
if( ext2IntNodeMap.find(source) == ext2IntNodeMap.end()) {
|
if( ext_to_int_id_map.find(source) == ext_to_int_id_map.end()) {
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
SimpleLogger().Write(logWARNING) <<
|
SimpleLogger().Write(logWARNING) <<
|
||||||
" unresolved source NodeID: " << source;
|
" unresolved source NodeID: " << source;
|
||||||
@ -162,8 +163,8 @@ NodeID readBinaryOSRMGraphFromStream(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
source = intNodeID->second;
|
source = intNodeID->second;
|
||||||
intNodeID = ext2IntNodeMap.find(target);
|
intNodeID = ext_to_int_id_map.find(target);
|
||||||
if(ext2IntNodeMap.find(target) == ext2IntNodeMap.end()) {
|
if(ext_to_int_id_map.find(target) == ext_to_int_id_map.end()) {
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
SimpleLogger().Write(logWARNING) <<
|
SimpleLogger().Write(logWARNING) <<
|
||||||
"unresolved target NodeID : " << target;
|
"unresolved target NodeID : " << target;
|
||||||
@ -215,7 +216,7 @@ NodeID readBinaryOSRMGraphFromStream(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
typename std::vector<EdgeT>::iterator newEnd = std::remove_if(edgeList.begin(), edgeList.end(), _ExcessRemover<EdgeT>());
|
typename std::vector<EdgeT>::iterator newEnd = std::remove_if(edgeList.begin(), edgeList.end(), _ExcessRemover<EdgeT>());
|
||||||
ext2IntNodeMap.clear();
|
ext_to_int_id_map.clear();
|
||||||
std::vector<EdgeT>(edgeList.begin(), newEnd).swap(edgeList); //remove excess candidates.
|
std::vector<EdgeT>(edgeList.begin(), newEnd).swap(edgeList); //remove excess candidates.
|
||||||
SimpleLogger().Write() << "Graph loaded ok and has " << edgeList.size() << " edges";
|
SimpleLogger().Write() << "Graph loaded ok and has " << edgeList.size() << " edges";
|
||||||
return n;
|
return n;
|
||||||
@ -225,13 +226,13 @@ NodeID readDTMPGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeList, s
|
|||||||
NodeID n, source, target, id;
|
NodeID n, source, target, id;
|
||||||
EdgeID m;
|
EdgeID m;
|
||||||
int dir, xcoord, ycoord;// direction (0 = open, 1 = forward, 2+ = open)
|
int dir, xcoord, ycoord;// direction (0 = open, 1 = forward, 2+ = open)
|
||||||
ExternalNodeMap ext2IntNodeMap;
|
ExternalNodeMap ext_to_int_id_map;
|
||||||
in >> n;
|
in >> n;
|
||||||
SimpleLogger().Write(logDEBUG) << "Importing n = " << n << " nodes ";
|
SimpleLogger().Write(logDEBUG) << "Importing n = " << n << " nodes ";
|
||||||
for (NodeID i=0; i<n; ++i) {
|
for (NodeID i=0; i<n; ++i) {
|
||||||
in >> id >> ycoord >> xcoord;
|
in >> id >> ycoord >> xcoord;
|
||||||
int2ExtNodeMap->push_back(NodeInfo(xcoord, ycoord, id));
|
int2ExtNodeMap->push_back(NodeInfo(xcoord, ycoord, id));
|
||||||
ext2IntNodeMap.insert(std::make_pair(id, i));
|
ext_to_int_id_map.insert(std::make_pair(id, i));
|
||||||
}
|
}
|
||||||
in >> m;
|
in >> m;
|
||||||
SimpleLogger().Write(logDEBUG) << " and " << m << " edges";
|
SimpleLogger().Write(logDEBUG) << " and " << m << " edges";
|
||||||
@ -321,13 +322,13 @@ NodeID readDTMPGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeList, s
|
|||||||
}
|
}
|
||||||
|
|
||||||
// translate the external NodeIDs to internal IDs
|
// translate the external NodeIDs to internal IDs
|
||||||
ExternalNodeMap::iterator intNodeID = ext2IntNodeMap.find(source);
|
ExternalNodeMap::iterator intNodeID = ext_to_int_id_map.find(source);
|
||||||
if( ext2IntNodeMap.find(source) == ext2IntNodeMap.end()) {
|
if( ext_to_int_id_map.find(source) == ext_to_int_id_map.end()) {
|
||||||
throw OSRMException("unresolvable source Node ID");
|
throw OSRMException("unresolvable source Node ID");
|
||||||
}
|
}
|
||||||
source = intNodeID->second;
|
source = intNodeID->second;
|
||||||
intNodeID = ext2IntNodeMap.find(target);
|
intNodeID = ext_to_int_id_map.find(target);
|
||||||
if(ext2IntNodeMap.find(target) == ext2IntNodeMap.end()) {
|
if(ext_to_int_id_map.find(target) == ext_to_int_id_map.end()) {
|
||||||
throw OSRMException("unresolvable target Node ID");
|
throw OSRMException("unresolvable target Node ID");
|
||||||
}
|
}
|
||||||
target = intNodeID->second;
|
target = intNodeID->second;
|
||||||
@ -339,7 +340,7 @@ NodeID readDTMPGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeList, s
|
|||||||
EdgeT inputEdge(source, target, 0, weight, forward, backward, type );
|
EdgeT inputEdge(source, target, 0, weight, forward, backward, type );
|
||||||
edgeList.push_back(inputEdge);
|
edgeList.push_back(inputEdge);
|
||||||
}
|
}
|
||||||
ext2IntNodeMap.clear();
|
ext_to_int_id_map.clear();
|
||||||
std::vector<EdgeT>(edgeList.begin(), edgeList.end()).swap(edgeList); //remove excess candidates.
|
std::vector<EdgeT>(edgeList.begin(), edgeList.end()).swap(edgeList); //remove excess candidates.
|
||||||
std::cout << "ok" << std::endl;
|
std::cout << "ok" << std::endl;
|
||||||
return n;
|
return n;
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
set(oldfile ${CMAKE_SOURCE_DIR}/../Util/UUID.cpp)
|
set(OLDFILE ${SOURCE_DIR}/Util/UUID.cpp)
|
||||||
if (EXISTS ${oldfile})
|
if (EXISTS ${OLDFILE})
|
||||||
file(REMOVE_RECURSE ${oldfile})
|
file(REMOVE_RECURSE ${OLDFILE})
|
||||||
endif()
|
endif()
|
||||||
|
file(MD5 ${SOURCE_DIR}/createHierarchy.cpp MD5PREPARE)
|
||||||
|
file(MD5 ${SOURCE_DIR}/DataStructures/StaticRTree.h MD5RTREE)
|
||||||
|
file(MD5 ${SOURCE_DIR}/DataStructures/NodeInformationHelpDesk.h MD5NODEINFO)
|
||||||
|
file(MD5 ${SOURCE_DIR}/Util/GraphLoader.h MD5GRAPH)
|
||||||
|
file(MD5 ${SOURCE_DIR}/Server/DataStructures/QueryObjectsStorage.cpp MD5OBJECTS)
|
||||||
|
|
||||||
file(MD5 ${CMAKE_SOURCE_DIR}/../createHierarchy.cpp MD5PREPARE)
|
CONFIGURE_FILE( ${SOURCE_DIR}/Util/UUID.cpp.in ${SOURCE_DIR}/Util/UUID.cpp )
|
||||||
file(MD5 ${CMAKE_SOURCE_DIR}/../DataStructures/StaticRTree.h MD5RTREE)
|
|
||||||
file(MD5 ${CMAKE_SOURCE_DIR}/../DataStructures/NodeInformationHelpDesk.h MD5NODEINFO)
|
|
||||||
file(MD5 ${CMAKE_SOURCE_DIR}/../Util/GraphLoader.h MD5GRAPH)
|
|
||||||
file(MD5 ${CMAKE_SOURCE_DIR}/../Server/DataStructures/QueryObjectsStorage.cpp MD5OBJECTS)
|
|
||||||
|
|
||||||
CONFIGURE_FILE( ${CMAKE_SOURCE_DIR}/../Util/UUID.cpp.in ${CMAKE_SOURCE_DIR}/../Util/UUID.cpp )
|
|
||||||
|
@ -85,7 +85,6 @@ function node_function (node)
|
|||||||
node.bollard = true
|
node.bollard = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return 1
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -93,19 +92,19 @@ function way_function (way)
|
|||||||
-- we dont route over areas
|
-- we dont route over areas
|
||||||
local area = way.tags:Find("area")
|
local area = way.tags:Find("area")
|
||||||
if ignore_areas and ("yes" == area) then
|
if ignore_areas and ("yes" == area) then
|
||||||
return 0
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- check if oneway tag is unsupported
|
-- check if oneway tag is unsupported
|
||||||
local oneway = way.tags:Find("oneway")
|
local oneway = way.tags:Find("oneway")
|
||||||
if "reversible" == oneway then
|
if "reversible" == oneway then
|
||||||
return 0
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Check if we are allowed to access the way
|
-- Check if we are allowed to access the way
|
||||||
local access = Access.find_access_tag(way, access_tags_hierachy)
|
local access = Access.find_access_tag(way, access_tags_hierachy)
|
||||||
if access_tag_blacklist[access] then
|
if access_tag_blacklist[access] then
|
||||||
return 0
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Second, parse the way according to these properties
|
-- Second, parse the way according to these properties
|
||||||
@ -212,7 +211,7 @@ function way_function (way)
|
|||||||
way.ignore_in_grid = true
|
way.ignore_in_grid = true
|
||||||
end
|
end
|
||||||
way.type = 1
|
way.type = 1
|
||||||
return 1
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- These are wrappers to parse vectors of nodes and ways and thus to speed up any tracing JIT
|
-- These are wrappers to parse vectors of nodes and ways and thus to speed up any tracing JIT
|
||||||
|
Loading…
Reference in New Issue
Block a user