mode flags

This commit is contained in:
Emil Tin 2013-03-18 19:59:15 +01:00
parent 67addfdb37
commit 42b7312cd2
34 changed files with 495 additions and 227 deletions

View File

@ -11,7 +11,7 @@ file(GLOB PrepareGlob Contractor/*.cpp)
set(PrepareSources createHierarchy.cpp ${PrepareGlob}) set(PrepareSources createHierarchy.cpp ${PrepareGlob})
add_executable(osrm-prepare ${PrepareSources}) add_executable(osrm-prepare ${PrepareSources})
file(GLOB RoutedGlob Server/DataStructures/*.cpp Descriptors/*.cpp) file(GLOB RoutedGlob Server/DataStructures/*.cpp Descriptors/*.cpp DataStructures/*.cpp)
set(RoutedSources routed.cpp ${RoutedGlob}) set(RoutedSources routed.cpp ${RoutedGlob})
add_executable(osrm-routed ${RoutedSources}) add_executable(osrm-routed ${RoutedSources})
set_target_properties(osrm-routed PROPERTIES COMPILE_FLAGS -DROUTED) set_target_properties(osrm-routed PROPERTIES COMPILE_FLAGS -DROUTED)

View File

@ -26,6 +26,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include <sys/time.h> #include <sys/time.h>
#endif #endif
#include "Contractor.h" #include "Contractor.h"
#include "TravelMode.h"
class ContractionCleanup { class ContractionCleanup {
private: private:
@ -64,6 +65,7 @@ public:
bool shortcut:1; bool shortcut:1;
bool forward:1; bool forward:1;
bool backward:1; bool backward:1;
TravelMode mode;
} data; } data;
bool operator<( const Edge& right ) const { bool operator<( const Edge& right ) const {
if ( source != right.source ) if ( source != right.source )

View File

@ -74,6 +74,7 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(int nodes, std::vector<NodeBasedEdg
edge.data.isAccessRestricted = i->isAccessRestricted(); edge.data.isAccessRestricted = i->isAccessRestricted();
edge.data.edgeBasedNodeID = edges.size(); edge.data.edgeBasedNodeID = edges.size();
edge.data.contraFlow = i->isContraFlow(); edge.data.contraFlow = i->isContraFlow();
edge.data.mode = i->mode();
edges.push_back( edge ); edges.push_back( edge );
if( edge.data.backward ) { if( edge.data.backward ) {
std::swap( edge.source, edge.target ); std::swap( edge.source, edge.target );
@ -147,6 +148,7 @@ void EdgeBasedGraphFactory::InsertEdgeBasedNode(
currentNode.id = data.edgeBasedNodeID; currentNode.id = data.edgeBasedNodeID;
currentNode.ignoreInGrid = data.ignoreInGrid; currentNode.ignoreInGrid = data.ignoreInGrid;
currentNode.weight = data.distance; currentNode.weight = data.distance;
currentNode.mode = data.mode;
edgeBasedNodes.push_back(currentNode); edgeBasedNodes.push_back(currentNode);
} }
@ -274,7 +276,9 @@ void EdgeBasedGraphFactory::Run(const char * originalEdgeDataFilename, lua_State
distance += speedProfile.trafficSignalPenalty; distance += speedProfile.trafficSignalPenalty;
} }
unsigned penalty = 0; unsigned penalty = 0;
TurnInstruction turnInstruction = AnalyzeTurn(u, v, w, penalty, myLuaState); bool contraflow;
TurnInstruction turnInstruction = AnalyzeTurn(u, v, w, contraflow, penalty, myLuaState);
if(turnInstruction == TurnInstructions.UTurn) if(turnInstruction == TurnInstructions.UTurn)
distance += speedProfile.uTurnPenalty; distance += speedProfile.uTurnPenalty;
// if(!edgeData1.isAccessRestricted && edgeData2.isAccessRestricted) { // if(!edgeData1.isAccessRestricted && edgeData2.isAccessRestricted) {
@ -283,11 +287,10 @@ void EdgeBasedGraphFactory::Run(const char * originalEdgeDataFilename, lua_State
// } // }
distance += penalty; distance += penalty;
//distance += heightPenalty; //distance += heightPenalty;
//distance += ComputeTurnPenalty(u, v, w); //distance += ComputeTurnPenalty(u, v, w);
assert(edgeData1.edgeBasedNodeID != edgeData2.edgeBasedNodeID); assert(edgeData1.edgeBasedNodeID != edgeData2.edgeBasedNodeID);
OriginalEdgeData oed(v,edgeData2.nameID, turnInstruction); OriginalEdgeData oed(v,edgeData2.nameID, turnInstruction, edgeData2.mode);
original_edge_data_vector.push_back(oed); original_edge_data_vector.push_back(oed);
++numberOfOriginalEdges; ++numberOfOriginalEdges;
@ -326,7 +329,7 @@ void EdgeBasedGraphFactory::Run(const char * originalEdgeDataFilename, lua_State
INFO("Generated " << edgeBasedNodes.size() << " edge based nodes"); INFO("Generated " << edgeBasedNodes.size() << " edge based nodes");
} }
TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w, unsigned& penalty, lua_State *myLuaState) const { TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w, bool& contraflow, unsigned& penalty, lua_State *myLuaState) const {
const double angle = GetAngleBetweenTwoEdges(inputNodeInfoList[u], inputNodeInfoList[v], inputNodeInfoList[w]); const double angle = GetAngleBetweenTwoEdges(inputNodeInfoList[u], inputNodeInfoList[v], inputNodeInfoList[w]);
if( speedProfile.has_turn_penalty_function ) { if( speedProfile.has_turn_penalty_function ) {
@ -351,12 +354,7 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(const NodeID u, const NodeID
_NodeBasedDynamicGraph::EdgeData & data1 = _nodeBasedGraph->GetEdgeData(edge1); _NodeBasedDynamicGraph::EdgeData & data1 = _nodeBasedGraph->GetEdgeData(edge1);
_NodeBasedDynamicGraph::EdgeData & data2 = _nodeBasedGraph->GetEdgeData(edge2); _NodeBasedDynamicGraph::EdgeData & data2 = _nodeBasedGraph->GetEdgeData(edge2);
if(!data1.contraFlow && data2.contraFlow) { contraflow = data2.contraFlow;
return TurnInstructions.EnterAgainstAllowedDirection;
}
if(data1.contraFlow && !data2.contraFlow) {
return TurnInstructions.LeaveAgainstAllowedDirection;
}
//roundabouts need to be handled explicitely //roundabouts need to be handled explicitely
if(data1.roundabout && data2.roundabout) { if(data1.roundabout && data2.roundabout) {
@ -379,8 +377,8 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(const NodeID u, const NodeID
} }
} }
//If street names stay the same and if we are certain that it is not a roundabout, we skip it. //If street names and modes stay the same and if we are certain that it is not a roundabout, we skip it.
if( (data1.nameID == data2.nameID) && (0 != data1.nameID)) { if( (data1.nameID == data2.nameID) && (data1.mode == data2.mode) && (0 != data1.nameID)) {
return TurnInstructions.NoTurn; return TurnInstructions.NoTurn;
} }
if( (data1.nameID == data2.nameID) && (0 == data1.nameID) && (_nodeBasedGraph->GetOutDegree(v) <= 2) ) { if( (data1.nameID == data2.nameID) && (0 == data1.nameID) && (_nodeBasedGraph->GetOutDegree(v) <= 2) ) {

View File

@ -77,6 +77,7 @@ public:
NodeID nameID; NodeID nameID;
unsigned weight:31; unsigned weight:31;
bool ignoreInGrid:1; bool ignoreInGrid:1;
TravelMode mode;
}; };
struct SpeedProfileProperties{ struct SpeedProfileProperties{
@ -99,6 +100,7 @@ private:
bool roundabout:1; bool roundabout:1;
bool ignoreInGrid:1; bool ignoreInGrid:1;
bool contraFlow:1; bool contraFlow:1;
TravelMode mode;
}; };
struct _EdgeBasedEdgeData { struct _EdgeBasedEdgeData {
@ -108,6 +110,7 @@ private:
bool forward; bool forward;
bool backward; bool backward;
TurnInstruction turnInstruction; TurnInstruction turnInstruction;
TravelMode mode;
}; };
typedef DynamicGraph< _NodeBasedEdgeData > _NodeBasedDynamicGraph; typedef DynamicGraph< _NodeBasedEdgeData > _NodeBasedDynamicGraph;
@ -147,7 +150,7 @@ public:
void GetEdgeBasedEdges( DeallocatingVector< EdgeBasedEdge >& edges ); void GetEdgeBasedEdges( DeallocatingVector< EdgeBasedEdge >& edges );
void GetEdgeBasedNodes( DeallocatingVector< EdgeBasedNode> & nodes); void GetEdgeBasedNodes( DeallocatingVector< 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, unsigned& penalty, lua_State *myLuaState) const; TurnInstruction AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w, bool& contraflow, unsigned& penalty, lua_State *myLuaState) const;
unsigned GetNumberOfNodes() const; unsigned GetNumberOfNodes() const;
}; };

View File

@ -22,16 +22,18 @@ or see http://www.gnu.org/licenses/agpl.txt.
#define GRIDEDGE_H_ #define GRIDEDGE_H_
#include "Coordinate.h" #include "Coordinate.h"
#include "TravelMode.h"
struct _GridEdge { struct _GridEdge {
_GridEdge(NodeID n, NodeID na, int w, _Coordinate sc, _Coordinate tc, bool bttc) : edgeBasedNode(n), nameID(na), weight(w), startCoord(sc), targetCoord(tc), belongsToTinyComponent(bttc) {} _GridEdge(NodeID n, NodeID na, int w, _Coordinate sc, _Coordinate tc, bool bttc, TravelMode _mode) : edgeBasedNode(n), nameID(na), weight(w), startCoord(sc), targetCoord(tc), belongsToTinyComponent(bttc), mode(_mode) {}
_GridEdge() : edgeBasedNode(UINT_MAX), nameID(UINT_MAX), weight(INT_MAX), belongsToTinyComponent(false) {} _GridEdge() : edgeBasedNode(UINT_MAX), nameID(UINT_MAX), weight(INT_MAX), belongsToTinyComponent(false), mode(0) {}
NodeID edgeBasedNode; NodeID edgeBasedNode;
NodeID nameID; NodeID nameID;
int weight; int weight;
_Coordinate startCoord; _Coordinate startCoord;
_Coordinate targetCoord; _Coordinate targetCoord;
bool belongsToTinyComponent; bool belongsToTinyComponent;
TravelMode mode;
bool operator< ( const _GridEdge& right) const { bool operator< ( const _GridEdge& right) const {
return edgeBasedNode < right.edgeBasedNode; return edgeBasedNode < right.edgeBasedNode;

View File

@ -23,6 +23,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include <cassert> #include <cassert>
#include "TravelMode.h"
class NodeBasedEdge { class NodeBasedEdge {
public: public:
@ -40,8 +42,8 @@ public:
return (source() < e.source()); return (source() < e.source());
} }
explicit NodeBasedEdge(NodeID s, NodeID t, NodeID n, EdgeWeight w, bool f, bool b, short ty, bool ra, bool ig, bool ar, bool cf) : explicit NodeBasedEdge(NodeID s, NodeID t, NodeID n, EdgeWeight w, bool f, bool b, short ty, bool ra, bool ig, bool ar, bool cf, TravelMode mode) :
_source(s), _target(t), _name(n), _weight(w), forward(f), backward(b), _type(ty), _roundabout(ra), _ignoreInGrid(ig), _accessRestricted(ar), _contraFlow(cf) { if(ty < 0) {ERR("Type: " << ty);}; } _source(s), _target(t), _name(n), _weight(w), forward(f), backward(b), _type(ty), _roundabout(ra), _ignoreInGrid(ig), _accessRestricted(ar), _contraFlow(cf), _mode(mode) { if(ty < 0) {ERR("Type: " << ty);}; }
NodeID target() const {return _target; } NodeID target() const {return _target; }
NodeID source() const {return _source; } NodeID source() const {return _source; }
@ -56,6 +58,7 @@ public:
bool ignoreInGrid() const { return _ignoreInGrid; } bool ignoreInGrid() const { return _ignoreInGrid; }
bool isAccessRestricted() const { return _accessRestricted; } bool isAccessRestricted() const { return _accessRestricted; }
bool isContraFlow() const { return _contraFlow; } bool isContraFlow() const { return _contraFlow; }
TravelMode mode() const { return _mode; }
NodeID _source; NodeID _source;
NodeID _target; NodeID _target;
@ -68,11 +71,12 @@ public:
bool _ignoreInGrid; bool _ignoreInGrid;
bool _accessRestricted; bool _accessRestricted;
bool _contraFlow; bool _contraFlow;
TravelMode _mode;
private: private:
/** Default constructor. target and weight are set to 0.*/ /** 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. _source(0), _target(0), _name(0), _weight(0), forward(0), backward(0), _type(0), _roundabout(false), _ignoreInGrid(false), _accessRestricted(false), _contraFlow(false), _mode(0) { assert(false); } //shall not be used.
}; };
@ -127,7 +131,7 @@ public:
EdgeWeight weight() const {return m_weight; } EdgeWeight weight() const {return m_weight; }
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;

113
DataStructures/NNGrid.cpp Normal file
View File

@ -0,0 +1,113 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#include "../typedefs.h"
#include "NNGrid.h"
#include "NodeInformationHelpDesk.h"
bool NNGrid::FindPhantomNodeForCoordinate( const _Coordinate & location, PhantomNode & resultNode, const unsigned zoomLevel) {
bool ignoreTinyComponents = (zoomLevel <= 14);
// INFO("Coordinate: " << location << ", zoomLevel: " << zoomLevel << ", ignoring tinyComponentents: " << (ignoreTinyComponents ? "yes" : "no"));
// double time1 = get_timestamp();
bool foundNode = false;
const _Coordinate startCoord(100000*(lat2y(static_cast<double>(location.lat)/100000.)), location.lon);
/** search for point on edge close to source */
const unsigned fileIndex = GetFileIndexForLatLon(startCoord.lat, startCoord.lon);
std::vector<_GridEdge> candidates;
const int lowerBoundForLoop = (fileIndex < 32768 ? 0 : -32768);
for(int j = lowerBoundForLoop; (j < (32768+1)) && (fileIndex != UINT_MAX); j+=32768) {
for(int i = -1; i < 2; ++i){
// unsigned oldSize = candidates.size();
GetContentsOfFileBucketEnumerated(fileIndex+i+j, candidates);
// INFO("Getting fileIndex=" << fileIndex+i+j << " with " << candidates.size() - oldSize << " candidates");
}
}
// INFO("looked up " << candidates.size());
_GridEdge smallestEdge;
_Coordinate tmp, edgeStartCoord, edgeEndCoord;
double dist = std::numeric_limits<double>::max();
double r, tmpDist;
BOOST_FOREACH(const _GridEdge & candidate, candidates) {
if(candidate.belongsToTinyComponent && ignoreTinyComponents)
continue;
r = 0.;
tmpDist = ComputeDistance(startCoord, candidate.startCoord, candidate.targetCoord, tmp, &r);
// INFO("dist " << startCoord << "->[" << candidate.startCoord << "-" << candidate.targetCoord << "]=" << tmpDist );
// INFO("Looking at edge " << candidate.edgeBasedNode << " at distance " << tmpDist);
if(tmpDist < dist && !DoubleEpsilonCompare(dist, tmpDist)) {
// INFO("a) " << candidate.edgeBasedNode << ", dist: " << tmpDist << ", tinyCC: " << (candidate.belongsToTinyComponent ? "yes" : "no"));
dist = tmpDist;
resultNode.edgeBasedNode = candidate.edgeBasedNode;
resultNode.nodeBasedEdgeNameID = candidate.nameID;
resultNode.mode1 = candidate.mode;
resultNode.mode2 = 0;
resultNode.weight1 = candidate.weight;
resultNode.weight2 = INT_MAX;
resultNode.location.lat = tmp.lat;
resultNode.location.lon = tmp.lon;
edgeStartCoord = candidate.startCoord;
edgeEndCoord = candidate.targetCoord;
foundNode = true;
smallestEdge = candidate;
//} else if(tmpDist < dist) {
//INFO("a) ignored " << candidate.edgeBasedNode << " at distance " << std::fabs(dist - tmpDist));
} else if(DoubleEpsilonCompare(dist, tmpDist) && 1 == std::abs(static_cast<int>(candidate.edgeBasedNode)-static_cast<int>(resultNode.edgeBasedNode) ) && CoordinatesAreEquivalent(edgeStartCoord, candidate.startCoord, edgeEndCoord, candidate.targetCoord)) {
resultNode.edgeBasedNode = std::min(candidate.edgeBasedNode, resultNode.edgeBasedNode);
resultNode.weight2 = candidate.weight;
resultNode.mode2 = candidate.mode;
//INFO("b) " << candidate.edgeBasedNode << ", dist: " << tmpDist);
}
}
// INFO("startcoord: " << smallestEdge.startCoord << ", tgtcoord" << smallestEdge.targetCoord << "result: " << newEndpoint);
// INFO("length of old edge: " << ApproximateDistance(smallestEdge.startCoord, smallestEdge.targetCoord));
// INFO("Length of new edge: " << ApproximateDistance(smallestEdge.startCoord, newEndpoint));
// assert(!resultNode.isBidirected() || (resultNode.weight1 == resultNode.weight2));
// if(resultNode.weight1 != resultNode.weight2) {
// INFO("-> Weight1: " << resultNode.weight1 << ", weight2: " << resultNode.weight2);
// INFO("-> node: " << resultNode.edgeBasedNode << ", bidir: " << (resultNode.isBidirected() ? "yes" : "no"));
// }
// INFO("startCoord: " << smallestEdge.startCoord << "; targetCoord: " << smallestEdge.targetCoord << "; newEndpoint: " << resultNode.location);
const double ratio = (foundNode ? std::min(1., ApproximateDistance(smallestEdge.startCoord, resultNode.location)/ApproximateDistance(smallestEdge.startCoord, smallestEdge.targetCoord)) : 0);
resultNode.location.lat = round(100000.*(y2lat(static_cast<double>(resultNode.location.lat)/100000.)));
// INFO("Length of vector: " << ApproximateDistance(smallestEdge.startCoord, resultNode.location)/ApproximateDistance(smallestEdge.startCoord, smallestEdge.targetCoord));
//Hack to fix rounding errors and wandering via nodes.
if(std::abs(location.lon - resultNode.location.lon) == 1)
resultNode.location.lon = location.lon;
if(std::abs(location.lat - resultNode.location.lat) == 1)
resultNode.location.lat = location.lat;
resultNode.weight1 *= ratio;
if(INT_MAX != resultNode.weight2) {
resultNode.weight2 *= (1.-ratio);
}
resultNode.ratio = ratio;
// INFO("start: " << edgeStartCoord << ", end: " << edgeEndCoord);
// INFO("selected node: " << resultNode.edgeBasedNode << ", bidirected: " << (resultNode.isBidirected() ? "yes" : "no"));
// INFO("New weight1: " << resultNode.weight1 << ", new weight2: " << resultNode.weight2 << ", ratio: " << ratio);
// INFO("distance to input coordinate: " << ApproximateDistance(location, resultNode.location) << "\n--");
// double time2 = get_timestamp();
// INFO("NN-Lookup in " << 1000*(time2-time1) << "ms");
return foundNode;
}

View File

@ -51,37 +51,31 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "StaticGraph.h" #include "StaticGraph.h"
#include "TimingUtil.h" #include "TimingUtil.h"
#include "../Algorithms/Bresenham.h" #include "../Algorithms/Bresenham.h"
#include "QueryEdge.h"
namespace NNGrid{ class NodeInformationHelpDesk;
class QueryGraph;
static boost::thread_specific_ptr<std::ifstream> localStream; static boost::thread_specific_ptr<std::ifstream> localStream;
template<bool WriteAccess = false>
class NNGrid { class NNGrid {
public: public:
NNGrid() /*: cellCache(500), fileCache(500)*/ { NNGrid() : nodeHelpDesk(NULL) {}
ramIndexTable.resize((1024*1024), std::numeric_limits<uint64_t>::max());
}
NNGrid(const char* rif, const char* _i, NodeInformationHelpDesk* _nodeHelpDesk, StaticGraph<QueryEdge::EdgeData>* g) : nodeHelpDesk(_nodeHelpDesk), graph(g) {
NNGrid(const char* rif, const char* _i) { nodeHelpDesk = _nodeHelpDesk;
if(WriteAccess) {
ERR("Not available in Write mode");
}
iif = std::string(_i); iif = std::string(_i);
ramIndexTable.resize((1024*1024), std::numeric_limits<uint64_t>::max()); ramIndexTable.resize((1024*1024), std::numeric_limits<uint64_t>::max());
ramInFile.open(rif, std::ios::in | std::ios::binary); ramInFile.open(rif, std::ios::in | std::ios::binary);
if(!ramInFile) { ERR(rif << " not found"); } if(!ramInFile) { ERR(rif << " not found"); }
} }
~NNGrid() { ~NNGrid() {
if(ramInFile.is_open()) ramInFile.close(); if(ramInFile.is_open()) ramInFile.close();
#ifndef ROUTED
if (WriteAccess) {
entries.clear();
}
#endif
if(localStream.get() && localStream->is_open()) { if(localStream.get() && localStream->is_open()) {
localStream->close(); localStream->close();
} }
@ -106,7 +100,7 @@ public:
int slon = edge.lon1; int slon = edge.lon1;
int tlat = 100000*lat2y(edge.lat2/100000.); int tlat = 100000*lat2y(edge.lat2/100000.);
int tlon = edge.lon2; int tlon = edge.lon2;
AddEdge( _GridEdge( edge.id, edge.nameID, edge.weight, _Coordinate(slat, slon), _Coordinate(tlat, tlon), edge.belongsToTinyComponent ) ); AddEdge( _GridEdge( edge.id, edge.nameID, edge.weight, _Coordinate(slat, slon), _Coordinate(tlat, tlon), edge.belongsToTinyComponent, edge.mode ) );
} }
if( 0 == entries.size() ) { if( 0 == entries.size() ) {
ERR("No viable edges for nearest neighbor index. Aborting"); ERR("No viable edges for nearest neighbor index. Aborting");
@ -159,90 +153,7 @@ public:
return (a == b && c == d) || (a == c && b == d) || (a == d && b == c); return (a == b && c == d) || (a == c && b == d) || (a == d && b == c);
} }
bool FindPhantomNodeForCoordinate( const _Coordinate & location, PhantomNode & resultNode, const unsigned zoomLevel) { bool FindPhantomNodeForCoordinate( const _Coordinate & location, PhantomNode & resultNode, const unsigned zoomLevel);
bool ignoreTinyComponents = (zoomLevel <= 14);
// INFO("Coordinate: " << location << ", zoomLevel: " << zoomLevel << ", ignoring tinyComponentents: " << (ignoreTinyComponents ? "yes" : "no"));
// double time1 = get_timestamp();
bool foundNode = false;
const _Coordinate startCoord(100000*(lat2y(static_cast<double>(location.lat)/100000.)), location.lon);
/** search for point on edge close to source */
const unsigned fileIndex = GetFileIndexForLatLon(startCoord.lat, startCoord.lon);
std::vector<_GridEdge> candidates;
const int lowerBoundForLoop = (fileIndex < 32768 ? 0 : -32768);
for(int j = lowerBoundForLoop; (j < (32768+1)) && (fileIndex != UINT_MAX); j+=32768) {
for(int i = -1; i < 2; ++i){
// unsigned oldSize = candidates.size();
GetContentsOfFileBucketEnumerated(fileIndex+i+j, candidates);
// INFO("Getting fileIndex=" << fileIndex+i+j << " with " << candidates.size() - oldSize << " candidates");
}
}
// INFO("looked up " << candidates.size());
_GridEdge smallestEdge;
_Coordinate tmp, edgeStartCoord, edgeEndCoord;
double dist = std::numeric_limits<double>::max();
double r, tmpDist;
BOOST_FOREACH(const _GridEdge & candidate, candidates) {
if(candidate.belongsToTinyComponent && ignoreTinyComponents)
continue;
r = 0.;
tmpDist = ComputeDistance(startCoord, candidate.startCoord, candidate.targetCoord, tmp, &r);
// INFO("dist " << startCoord << "->[" << candidate.startCoord << "-" << candidate.targetCoord << "]=" << tmpDist );
// INFO("Looking at edge " << candidate.edgeBasedNode << " at distance " << tmpDist);
if(tmpDist < dist && !DoubleEpsilonCompare(dist, tmpDist)) {
// INFO("a) " << candidate.edgeBasedNode << ", dist: " << tmpDist << ", tinyCC: " << (candidate.belongsToTinyComponent ? "yes" : "no"));
dist = tmpDist;
resultNode.edgeBasedNode = candidate.edgeBasedNode;
resultNode.nodeBasedEdgeNameID = candidate.nameID;
resultNode.weight1 = candidate.weight;
resultNode.weight2 = INT_MAX;
resultNode.location.lat = tmp.lat;
resultNode.location.lon = tmp.lon;
edgeStartCoord = candidate.startCoord;
edgeEndCoord = candidate.targetCoord;
foundNode = true;
smallestEdge = candidate;
//} else if(tmpDist < dist) {
//INFO("a) ignored " << candidate.edgeBasedNode << " at distance " << std::fabs(dist - tmpDist));
} else if(DoubleEpsilonCompare(dist, tmpDist) && 1 == std::abs(static_cast<int>(candidate.edgeBasedNode)-static_cast<int>(resultNode.edgeBasedNode) ) && CoordinatesAreEquivalent(edgeStartCoord, candidate.startCoord, edgeEndCoord, candidate.targetCoord)) {
resultNode.edgeBasedNode = std::min(candidate.edgeBasedNode, resultNode.edgeBasedNode);
resultNode.weight2 = candidate.weight;
//INFO("b) " << candidate.edgeBasedNode << ", dist: " << tmpDist);
}
}
// INFO("startcoord: " << smallestEdge.startCoord << ", tgtcoord" << smallestEdge.targetCoord << "result: " << newEndpoint);
// INFO("length of old edge: " << ApproximateDistance(smallestEdge.startCoord, smallestEdge.targetCoord));
// INFO("Length of new edge: " << ApproximateDistance(smallestEdge.startCoord, newEndpoint));
// assert(!resultNode.isBidirected() || (resultNode.weight1 == resultNode.weight2));
// if(resultNode.weight1 != resultNode.weight2) {
// INFO("-> Weight1: " << resultNode.weight1 << ", weight2: " << resultNode.weight2);
// INFO("-> node: " << resultNode.edgeBasedNode << ", bidir: " << (resultNode.isBidirected() ? "yes" : "no"));
// }
// INFO("startCoord: " << smallestEdge.startCoord << "; targetCoord: " << smallestEdge.targetCoord << "; newEndpoint: " << resultNode.location);
const double ratio = (foundNode ? std::min(1., ApproximateDistance(smallestEdge.startCoord, resultNode.location)/ApproximateDistance(smallestEdge.startCoord, smallestEdge.targetCoord)) : 0);
resultNode.location.lat = round(100000.*(y2lat(static_cast<double>(resultNode.location.lat)/100000.)));
// INFO("Length of vector: " << ApproximateDistance(smallestEdge.startCoord, resultNode.location)/ApproximateDistance(smallestEdge.startCoord, smallestEdge.targetCoord));
//Hack to fix rounding errors and wandering via nodes.
if(std::abs(location.lon - resultNode.location.lon) == 1)
resultNode.location.lon = location.lon;
if(std::abs(location.lat - resultNode.location.lat) == 1)
resultNode.location.lat = location.lat;
resultNode.weight1 *= ratio;
if(INT_MAX != resultNode.weight2) {
resultNode.weight2 *= (1.-ratio);
}
resultNode.ratio = ratio;
// INFO("start: " << edgeStartCoord << ", end: " << edgeEndCoord);
// INFO("selected node: " << resultNode.edgeBasedNode << ", bidirected: " << (resultNode.isBidirected() ? "yes" : "no"));
// INFO("New weight1: " << resultNode.weight1 << ", new weight2: " << resultNode.weight2 << ", ratio: " << ratio);
// INFO("distance to input coordinate: " << ApproximateDistance(location, resultNode.location) << "\n--");
// double time2 = get_timestamp();
// INFO("NN-Lookup in " << 1000*(time2-time1) << "ms");
return foundNode;
}
bool FindRoutingStarts(const _Coordinate& start, const _Coordinate& target, PhantomNodes & routingStarts, unsigned zoomLevel) { bool FindRoutingStarts(const _Coordinate& start, const _Coordinate& target, PhantomNodes & routingStarts, unsigned zoomLevel) {
routingStarts.Reset(); routingStarts.Reset();
@ -282,7 +193,7 @@ public:
} }
private: protected:
inline unsigned GetCellIndexFromRAMAndFileIndex(const unsigned ramIndex, const unsigned fileIndex) const { inline unsigned GetCellIndexFromRAMAndFileIndex(const unsigned ramIndex, const unsigned fileIndex) const {
unsigned lineBase = ramIndex/1024; unsigned lineBase = ramIndex/1024;
lineBase = lineBase*32*32768; lineBase = lineBase*32*32768;
@ -589,14 +500,30 @@ private:
std::ofstream indexOutFile; std::ofstream indexOutFile;
stxxl::vector<GridEntry> entries; stxxl::vector<GridEntry> entries;
#endif #endif
NodeInformationHelpDesk* nodeHelpDesk;
std::vector<uint64_t> ramIndexTable; //8 MB for first level index in RAM std::vector<uint64_t> ramIndexTable; //8 MB for first level index in RAM
std::string iif; std::string iif;
bool writeAccess;
StaticGraph<QueryEdge::EdgeData>* graph;
// LRUCache<int,std::vector<unsigned> > cellCache; // LRUCache<int,std::vector<unsigned> > cellCache;
// LRUCache<int,std::vector<_Edge> > fileCache; // LRUCache<int,std::vector<_Edge> > fileCache;
}; };
}
typedef NNGrid::NNGrid<false> ReadOnlyGrid; class ReadOnlyGrid : public NNGrid {
typedef NNGrid::NNGrid<true > WritableGrid; public:
ReadOnlyGrid(const char* rif, const char* _i, NodeInformationHelpDesk* _nodeHelpDesk, StaticGraph<QueryEdge::EdgeData>* g) : NNGrid(rif,_i,_nodeHelpDesk,g) {}
};
class WritableGrid : public NNGrid {
public:
WritableGrid() {
ramIndexTable.resize((1024*1024), std::numeric_limits<uint64_t>::max());
}
~WritableGrid() {
#ifndef ROUTED
entries.clear();
#endif
}
};
#endif /* NNGRID_H_ */ #endif /* NNGRID_H_ */

View File

@ -32,11 +32,14 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "NNGrid.h" #include "NNGrid.h"
#include "PhantomNodes.h" #include "PhantomNodes.h"
#include "NodeCoords.h" #include "NodeCoords.h"
#include "TravelMode.h"
class QueryGraph;
class NodeInformationHelpDesk : boost::noncopyable{ class NodeInformationHelpDesk : boost::noncopyable{
public: public:
NodeInformationHelpDesk(const char* ramIndexInput, const char* fileIndexInput, const unsigned _numberOfNodes, const unsigned crc) : numberOfNodes(_numberOfNodes), checkSum(crc) { NodeInformationHelpDesk(const char* ramIndexInput, const char* fileIndexInput, const unsigned _numberOfNodes, const unsigned crc, StaticGraph<QueryEdge::EdgeData>* graph) : numberOfNodes(_numberOfNodes), checkSum(crc) {
readOnlyGrid = new ReadOnlyGrid(ramIndexInput,fileIndexInput); readOnlyGrid = new ReadOnlyGrid(ramIndexInput,fileIndexInput, this, graph);
assert(0 == coordinateVector.size()); assert(0 == coordinateVector.size());
} }
@ -64,6 +67,7 @@ public:
origEdgeData_viaNode.resize(numberOfOrigEdges); origEdgeData_viaNode.resize(numberOfOrigEdges);
origEdgeData_nameID.resize(numberOfOrigEdges); origEdgeData_nameID.resize(numberOfOrigEdges);
origEdgeData_turnInstruction.resize(numberOfOrigEdges); origEdgeData_turnInstruction.resize(numberOfOrigEdges);
origEdgeData_mode.resize(numberOfOrigEdges);
OriginalEdgeData deserialized_originalEdgeData; OriginalEdgeData deserialized_originalEdgeData;
for(unsigned i = 0; i < numberOfOrigEdges; ++i) { for(unsigned i = 0; i < numberOfOrigEdges; ++i) {
@ -71,6 +75,7 @@ public:
origEdgeData_viaNode[i] = deserialized_originalEdgeData.viaNode; origEdgeData_viaNode[i] = deserialized_originalEdgeData.viaNode;
origEdgeData_nameID[i] = deserialized_originalEdgeData.nameID; origEdgeData_nameID[i] = deserialized_originalEdgeData.nameID;
origEdgeData_turnInstruction[i] = deserialized_originalEdgeData.turnInstruction; origEdgeData_turnInstruction[i] = deserialized_originalEdgeData.turnInstruction;
origEdgeData_mode[i] = deserialized_originalEdgeData.mode;
} }
edgesInStream.close(); edgesInStream.close();
DEBUG("Loaded " << numberOfOrigEdges << " orig edges"); DEBUG("Loaded " << numberOfOrigEdges << " orig edges");
@ -100,6 +105,10 @@ public:
return origEdgeData_turnInstruction.at(id); return origEdgeData_turnInstruction.at(id);
} }
inline TravelMode getModeFromEdgeID(const unsigned id) const {
return origEdgeData_mode.at(id);
}
inline NodeID getNumberOfNodes() const { return numberOfNodes; } inline NodeID getNumberOfNodes() const { return numberOfNodes; }
inline NodeID getNumberOfNodes2() const { return coordinateVector.size(); } inline NodeID getNumberOfNodes2() const { return coordinateVector.size(); }
@ -128,6 +137,7 @@ private:
std::vector<NodeID> origEdgeData_viaNode; std::vector<NodeID> origEdgeData_viaNode;
std::vector<unsigned> origEdgeData_nameID; std::vector<unsigned> origEdgeData_nameID;
std::vector<TurnInstruction> origEdgeData_turnInstruction; std::vector<TurnInstruction> origEdgeData_turnInstruction;
std::vector<TravelMode> origEdgeData_mode;
ReadOnlyGrid * readOnlyGrid; ReadOnlyGrid * readOnlyGrid;
const unsigned numberOfNodes; const unsigned numberOfNodes;

View File

@ -22,14 +22,17 @@ or see http://www.gnu.org/licenses/agpl.txt.
#define PHANTOMNODES_H_ #define PHANTOMNODES_H_
#include "Coordinate.h" #include "Coordinate.h"
#include "TravelMode.h"
struct PhantomNode { struct PhantomNode {
PhantomNode() : edgeBasedNode(UINT_MAX), nodeBasedEdgeNameID(UINT_MAX), weight1(INT_MAX), weight2(INT_MAX), ratio(0.) {} PhantomNode() : edgeBasedNode(UINT_MAX), nodeBasedEdgeNameID(UINT_MAX), weight1(INT_MAX), weight2(INT_MAX), ratio(0.), mode1(0), mode2(0) {}
NodeID edgeBasedNode; NodeID edgeBasedNode;
unsigned nodeBasedEdgeNameID; unsigned nodeBasedEdgeNameID;
int weight1; int weight1;
int weight2; int weight2;
double ratio; double ratio;
TravelMode mode1;
TravelMode mode2;
_Coordinate location; _Coordinate location;
void Reset() { void Reset() {
edgeBasedNode = UINT_MAX; edgeBasedNode = UINT_MAX;

View File

@ -24,22 +24,32 @@ or see http://www.gnu.org/licenses/agpl.txt.
#define QUERYEDGE_H_ #define QUERYEDGE_H_
#include "TurnInstructions.h" #include "TurnInstructions.h"
#include "TravelMode.h"
#include "../typedefs.h" #include "../typedefs.h"
#include <climits> #include <climits>
struct OriginalEdgeData{ struct OriginalEdgeData{
explicit OriginalEdgeData(NodeID v, unsigned n, TurnInstruction t) : viaNode(v), nameID(n), turnInstruction(t) {} explicit OriginalEdgeData(NodeID v, unsigned n, TurnInstruction t, TravelMode _mode) : viaNode(v), nameID(n), turnInstruction(t), mode(_mode) {}
OriginalEdgeData() : viaNode(UINT_MAX), nameID(UINT_MAX), turnInstruction(UCHAR_MAX) {} OriginalEdgeData() : viaNode(UINT_MAX), nameID(UINT_MAX), turnInstruction(UCHAR_MAX) {}
NodeID viaNode; NodeID viaNode;
unsigned nameID; unsigned nameID;
TurnInstruction turnInstruction; TurnInstruction turnInstruction;
TravelMode mode;
}; };
struct QueryEdge { struct QueryEdge {
NodeID source; NodeID source;
NodeID target; NodeID target;
struct EdgeData { struct EdgeData {
EdgeData() :
id(0),
shortcut(false),
distance(0),
forward(false),
backward(false)
{}
NodeID id:31; NodeID id:31;
bool shortcut:1; bool shortcut:1;
int distance:30; int distance:30;

View File

@ -33,10 +33,11 @@ struct SegmentInformation {
double bearing; double bearing;
TurnInstruction turnInstruction; TurnInstruction turnInstruction;
bool necessary; bool necessary;
SegmentInformation(const _Coordinate & loc, const NodeID nam, const double len, const unsigned dur, const TurnInstruction tInstr, const bool nec) : char mode;
location(loc), nameID(nam), length(len), duration(dur), bearing(0.), turnInstruction(tInstr), necessary(nec) {} SegmentInformation(const _Coordinate & loc, const NodeID nam, const double len, const unsigned dur, const TurnInstruction tInstr, const bool nec, const char mod) :
SegmentInformation(const _Coordinate & loc, const NodeID nam, const double len, const unsigned dur, const TurnInstruction tInstr) : location(loc), nameID(nam), length(len), duration(dur), bearing(0.), turnInstruction(tInstr), necessary(nec), mode(mod) {}
location(loc), nameID(nam), length(len), duration(dur), bearing(0.), turnInstruction(tInstr), necessary(tInstr != 0) {} SegmentInformation(const _Coordinate & loc, const NodeID nam, const double len, const unsigned dur, const TurnInstruction tInstr, const char mod) :
location(loc), nameID(nam), length(len), duration(dur), bearing(0.), turnInstruction(tInstr), necessary(tInstr != 0), mode(mod) {}
}; };
#endif /* SEGMENTINFORMATION_H_ */ #endif /* SEGMENTINFORMATION_H_ */

View File

@ -0,0 +1,26 @@
/*
open source routing machine
Copyright (C) Dennis Luxen, 2010
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU AFFERO General Public License as published by
the Free Software Foundation; either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt.
*/
#ifndef TRAVELMODE_H_
#define TRAVELMODE_H_
typedef unsigned char TravelMode;
#endif /* TRAVELMODE_H_ */

View File

@ -51,19 +51,20 @@ double DescriptionFactory::GetBearing(const _Coordinate& A, const _Coordinate& B
void DescriptionFactory::SetStartSegment(const PhantomNode & _startPhantom) { void DescriptionFactory::SetStartSegment(const PhantomNode & _startPhantom) {
startPhantom = _startPhantom; startPhantom = _startPhantom;
AppendSegment(_startPhantom.location, _PathData(0, _startPhantom.nodeBasedEdgeNameID, 10, _startPhantom.weight1)); AppendSegment(_startPhantom.location, _PathData(0, _startPhantom.nodeBasedEdgeNameID, 10, _startPhantom.weight1, _startPhantom.mode1));
} }
void DescriptionFactory::SetEndSegment(const PhantomNode & _targetPhantom) { void DescriptionFactory::SetEndSegment(const PhantomNode & _targetPhantom) {
targetPhantom = _targetPhantom; targetPhantom = _targetPhantom;
pathDescription.push_back(SegmentInformation(_targetPhantom.location, _targetPhantom.nodeBasedEdgeNameID, 0, _targetPhantom.weight1, 0, true) ); pathDescription.push_back(SegmentInformation(_targetPhantom.location, _targetPhantom.nodeBasedEdgeNameID, 0, _targetPhantom.weight1, 0, true, _targetPhantom.mode1) );
} }
void DescriptionFactory::AppendSegment(const _Coordinate & coordinate, const _PathData & data ) { void DescriptionFactory::AppendSegment(const _Coordinate & coordinate, const _PathData & data ) {
if(1 == pathDescription.size() && pathDescription.back().location == coordinate) { if(1 == pathDescription.size() && pathDescription.back().location == coordinate) {
pathDescription.back().nameID = data.nameID; pathDescription.back().nameID = data.nameID;
pathDescription.back().mode = data.mode;
} else { } else {
pathDescription.push_back(SegmentInformation(coordinate, data.nameID, 0, data.durationOfSegment, data.turnInstruction) ); pathDescription.push_back(SegmentInformation(coordinate, data.nameID, 0, data.durationOfSegment, data.turnInstruction, data.mode) );
} }
} }
@ -83,7 +84,6 @@ void DescriptionFactory::AppendUnencodedPolylineString(std::string &output) {
} }
void DescriptionFactory::Run(const SearchEngineT &sEngine, const unsigned zoomLevel) { void DescriptionFactory::Run(const SearchEngineT &sEngine, const unsigned zoomLevel) {
if(0 == pathDescription.size()) if(0 == pathDescription.size())
return; return;
@ -170,6 +170,7 @@ void DescriptionFactory::Run(const SearchEngineT &sEngine, const unsigned zoomLe
pathDescription.back().necessary = true; pathDescription.back().necessary = true;
pathDescription.back().turnInstruction = TurnInstructions.NoTurn; pathDescription.back().turnInstruction = TurnInstructions.NoTurn;
targetPhantom.nodeBasedEdgeNameID = (pathDescription.end()-2)->nameID; targetPhantom.nodeBasedEdgeNameID = (pathDescription.end()-2)->nameID;
targetPhantom.mode1 = (pathDescription.end()-2)->mode;
// INFO("Deleting last turn instruction"); // INFO("Deleting last turn instruction");
} }
} else { } else {
@ -182,7 +183,8 @@ void DescriptionFactory::Run(const SearchEngineT &sEngine, const unsigned zoomLe
pathDescription[0].turnInstruction = TurnInstructions.HeadOn; pathDescription[0].turnInstruction = TurnInstructions.HeadOn;
pathDescription[0].necessary = true; pathDescription[0].necessary = true;
startPhantom.nodeBasedEdgeNameID = pathDescription[0].nameID; startPhantom.nodeBasedEdgeNameID = pathDescription[0].nameID;
// INFO("Deleting first turn instruction, ratio: " << startPhantom.ratio << ", length: " << pathDescription[0].length); startPhantom.mode1 = pathDescription[0].mode;
// INFO("Deleting first turn instruction, ratio: " << startPhantom.ratio << ", length: " << pathDescription[0].length);
} }
} else { } else {
pathDescription[0].duration *= startPhantom.ratio; pathDescription[0].duration *= startPhantom.ratio;

View File

@ -312,7 +312,7 @@ public:
unsigned prefixSumOfNecessarySegments = 0; unsigned prefixSumOfNecessarySegments = 0;
roundAbout.leaveAtExit = 0; roundAbout.leaveAtExit = 0;
roundAbout.nameID = 0; roundAbout.nameID = 0;
std::string tmpDist, tmpLength, tmpDuration, tmpBearing, tmpInstruction; std::string tmpDist, tmpLength, tmpDuration, tmpBearing, tmpInstruction, tmpMode;
//Fetch data from Factory and generate a string from it. //Fetch data from Factory and generate a string from it.
BOOST_FOREACH(const SegmentInformation & segment, descriptionFactory.pathDescription) { BOOST_FOREACH(const SegmentInformation & segment, descriptionFactory.pathDescription) {
TurnInstruction currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag; TurnInstruction currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag;
@ -358,6 +358,11 @@ public:
reply.content += "\","; reply.content += "\",";
intToString(round(segment.bearing), tmpBearing); intToString(round(segment.bearing), tmpBearing);
reply.content += tmpBearing; reply.content += tmpBearing;
reply.content += ",";
intToString(segment.mode, tmpMode);
reply.content += tmpMode;
reply.content += "]"; reply.content += "]";
segmentVector.push_back( Segment(segment.nameID, segment.length, segmentVector.size() )); segmentVector.push_back( Segment(segment.nameID, segment.length, segmentVector.size() ));

View File

@ -25,6 +25,7 @@ extractor_callbacks(ec), scriptingEnvironment(se), luaState(NULL), use_turn_rest
luaState = se.getLuaStateForThreadID(0); luaState = se.getLuaStateForThreadID(0);
ReadUseRestrictionsSetting(); ReadUseRestrictionsSetting();
ReadRestrictionExceptions(); ReadRestrictionExceptions();
ReadModes();
} }
void BaseParser::ReadUseRestrictionsSetting() { void BaseParser::ReadUseRestrictionsSetting() {
@ -64,6 +65,28 @@ void BaseParser::ReadRestrictionExceptions() {
} }
} }
void BaseParser::ReadModes() {
if(lua_function_exists(luaState, "get_modes" )) {
//get list of modes
try {
luabind::call_function<void>(
luaState,
"get_modes",
boost::ref(modes)
);
BOOST_FOREACH(std::string & str, modes) {
INFO("mode found: " << str);
}
} catch (const luabind::error &er) {
lua_State* Ler=er.state();
report_errors(Ler, -1);
ERR(er.what());
}
} else {
INFO("Found no modes");
}
}
void BaseParser::report_errors(lua_State *L, const int status) const { void BaseParser::report_errors(lua_State *L, const int status) const {
if( 0!=status ) { if( 0!=status ) {
std::cerr << "-- " << lua_tostring(L, -1) << std::endl; std::cerr << "-- " << lua_tostring(L, -1) << std::endl;

View File

@ -46,6 +46,7 @@ public:
protected: protected:
virtual void ReadUseRestrictionsSetting(); virtual void ReadUseRestrictionsSetting();
virtual void ReadRestrictionExceptions(); virtual void ReadRestrictionExceptions();
virtual void ReadModes();
virtual bool ShouldIgnoreRestriction(const std::string& except_tag_string) const; virtual bool ShouldIgnoreRestriction(const std::string& except_tag_string) const;
ExtractorCallbacks* extractor_callbacks; ExtractorCallbacks* extractor_callbacks;
@ -53,7 +54,7 @@ protected:
lua_State* luaState; lua_State* luaState;
std::vector<std::string> restriction_exceptions; std::vector<std::string> restriction_exceptions;
bool use_turn_restrictions; bool use_turn_restrictions;
std::vector<std::string> modes;
}; };
#endif /* BASEPARSER_H_ */ #endif /* BASEPARSER_H_ */

View File

@ -257,6 +257,7 @@ void ExtractionContainers::PrepareData(const std::string & outputFileName, const
fout.write((char*)&edgeIT->ignoreInGrid, sizeof(bool)); fout.write((char*)&edgeIT->ignoreInGrid, sizeof(bool));
fout.write((char*)&edgeIT->isAccessRestricted, sizeof(bool)); fout.write((char*)&edgeIT->isAccessRestricted, sizeof(bool));
fout.write((char*)&edgeIT->isContraFlow, sizeof(bool)); fout.write((char*)&edgeIT->isContraFlow, sizeof(bool));
fout.write((char*)&edgeIT->mode, sizeof(unsigned char));
} }
++usedEdgeCounter; ++usedEdgeCounter;
++edgeIT; ++edgeIT;
@ -265,6 +266,8 @@ void ExtractionContainers::PrepareData(const std::string & outputFileName, const
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl; std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
std::cout << "[extractor] setting number of edges ... " << std::flush; std::cout << "[extractor] setting number of edges ... " << std::flush;
std::cout << "[extractor] number of edges: " << usedEdgeCounter << std::flush;
fout.seekp(positionInFile); fout.seekp(positionInFile);
fout.write((char*)&usedEdgeCounter, sizeof(unsigned)); fout.write((char*)&usedEdgeCounter, sizeof(unsigned));
fout.close(); fout.close();

View File

@ -69,7 +69,7 @@ void ExtractorCallbacks::wayFunction(ExtractionWay &parsed_way) {
DEBUG("found bogus way with id: " << parsed_way.id << " of size " << parsed_way.path.size()); DEBUG("found bogus way with id: " << parsed_way.id << " of size " << parsed_way.path.size());
return; return;
} }
if(0 < parsed_way.duration) { if(0 < parsed_way.duration) {
//TODO: iterate all way segments and set duration corresponding to the length of each segment //TODO: iterate all way segments and set duration corresponding to the length of each segment
parsed_way.speed = parsed_way.duration/(parsed_way.path.size()-1); parsed_way.speed = parsed_way.duration/(parsed_way.path.size()-1);
@ -108,7 +108,8 @@ void ExtractorCallbacks::wayFunction(ExtractionWay &parsed_way) {
parsed_way.roundabout, parsed_way.roundabout,
parsed_way.ignoreInGrid, parsed_way.ignoreInGrid,
(0 < parsed_way.duration), (0 < parsed_way.duration),
parsed_way.isAccessRestricted parsed_way.isAccessRestricted,
parsed_way.forward_mode
) )
); );
externalMemory->usedNodeIDs.push_back(parsed_way.path[n]); externalMemory->usedNodeIDs.push_back(parsed_way.path[n]);
@ -132,7 +133,8 @@ void ExtractorCallbacks::wayFunction(ExtractionWay &parsed_way) {
parsed_way.ignoreInGrid, parsed_way.ignoreInGrid,
(0 < parsed_way.duration), (0 < parsed_way.duration),
parsed_way.isAccessRestricted, parsed_way.isAccessRestricted,
(ExtractionWay::oneway == parsed_way.direction) (ExtractionWay::oneway == parsed_way.direction),
parsed_way.backward_mode
) )
); );
} }

View File

@ -35,6 +35,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "../DataStructures/NodeCoords.h" #include "../DataStructures/NodeCoords.h"
#include "../DataStructures/Restriction.h" #include "../DataStructures/Restriction.h"
#include "../DataStructures/TimingUtil.h" #include "../DataStructures/TimingUtil.h"
#include "../DataStructures/TravelMode.h"
#include "../typedefs.h" #include "../typedefs.h"
typedef boost::unordered_map<std::string, NodeID > StringMap; typedef boost::unordered_map<std::string, NodeID > StringMap;
@ -59,8 +60,10 @@ struct ExtractionWay {
roundabout = false; roundabout = false;
isAccessRestricted = false; isAccessRestricted = false;
ignoreInGrid = false; ignoreInGrid = false;
forward_mode = 0;
backward_mode = 0;
} }
enum Directions { enum Directions {
notSure = 0, oneway, bidirectional, opposite notSure = 0, oneway, bidirectional, opposite
}; };
@ -76,6 +79,8 @@ struct ExtractionWay {
bool roundabout; bool roundabout;
bool isAccessRestricted; bool isAccessRestricted;
bool ignoreInGrid; bool ignoreInGrid;
TravelMode forward_mode;
TravelMode backward_mode;
std::vector< NodeID > path; std::vector< NodeID > path;
HashTable<std::string, std::string> keyVals; HashTable<std::string, std::string> keyVals;
}; };
@ -89,13 +94,13 @@ struct ExtractorRelation {
}; };
struct InternalExtractorEdge { struct InternalExtractorEdge {
InternalExtractorEdge() : start(0), target(0), type(0), direction(0), speed(0), nameID(0), isRoundabout(false), ignoreInGrid(false), isDurationSet(false), isAccessRestricted(false), isContraFlow(false) {}; InternalExtractorEdge() : start(0), target(0), type(0), direction(0), speed(0), nameID(0), isRoundabout(false), ignoreInGrid(false), isDurationSet(false), isAccessRestricted(false), isContraFlow(false), mode(0) {};
InternalExtractorEdge(NodeID s, NodeID t) : start(s), target(t), type(0), direction(0), speed(0), nameID(0), isRoundabout(false), ignoreInGrid(false), isDurationSet(false), isAccessRestricted(false), isContraFlow(false) { } InternalExtractorEdge(NodeID s, NodeID t) : start(s), target(t), type(0), direction(0), speed(0), nameID(0), isRoundabout(false), ignoreInGrid(false), isDurationSet(false), isAccessRestricted(false), isContraFlow(false) { }
InternalExtractorEdge(NodeID s, NodeID t, short tp, short d, double sp): start(s), target(t), type(tp), direction(d), speed(sp), nameID(0), isRoundabout(false), ignoreInGrid(false), isDurationSet(false), isAccessRestricted(false), isContraFlow(false) { } InternalExtractorEdge(NodeID s, NodeID t, short tp, short d, double sp): start(s), target(t), type(tp), direction(d), speed(sp), nameID(0), isRoundabout(false), ignoreInGrid(false), isDurationSet(false), isAccessRestricted(false), isContraFlow(false) { }
InternalExtractorEdge(NodeID s, NodeID t, short tp, short d, double sp, unsigned nid, bool isra, bool iing, bool ids, bool iar): start(s), target(t), type(tp), direction(d), speed(sp), nameID(nid), isRoundabout(isra), ignoreInGrid(iing), isDurationSet(ids), isAccessRestricted(iar), isContraFlow(false) { InternalExtractorEdge(NodeID s, NodeID t, short tp, short d, double sp, unsigned nid, bool isra, bool iing, bool ids, bool iar, TravelMode _mode): start(s), target(t), type(tp), direction(d), speed(sp), nameID(nid), isRoundabout(isra), ignoreInGrid(iing), isDurationSet(ids), isAccessRestricted(iar), isContraFlow(false), mode(_mode) {
assert(0 <= type); assert(0 <= type);
} }
InternalExtractorEdge(NodeID s, NodeID t, short tp, short d, double sp, unsigned nid, bool isra, bool iing, bool ids, bool iar, bool icf): start(s), target(t), type(tp), direction(d), speed(sp), nameID(nid), isRoundabout(isra), ignoreInGrid(iing), isDurationSet(ids), isAccessRestricted(iar), isContraFlow(icf) { InternalExtractorEdge(NodeID s, NodeID t, short tp, short d, double sp, unsigned nid, bool isra, bool iing, bool ids, bool iar, bool icf, TravelMode _mode) : start(s), target(t), type(tp), direction(d), speed(sp), nameID(nid), isRoundabout(isra), ignoreInGrid(iing), isDurationSet(ids), isAccessRestricted(iar), isContraFlow(false), mode(_mode) {
assert(0 <= type); assert(0 <= type);
} }
NodeID start; NodeID start;
@ -109,7 +114,8 @@ struct InternalExtractorEdge {
bool isDurationSet; bool isDurationSet;
bool isAccessRestricted; bool isAccessRestricted;
bool isContraFlow; bool isContraFlow;
TravelMode mode;
_Coordinate startCoord; _Coordinate startCoord;
_Coordinate targetCoord; _Coordinate targetCoord;

View File

@ -319,7 +319,7 @@ inline void PBFParser::parseWay(_ThreadData * threadData) {
#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 = waysToParse[i]; ExtractionWay & w = waysToParse[i];
ParseWayInLua( w, scriptingEnvironment.getLuaStateForThreadID(omp_get_thread_num()) ); ParseWayInLua( w, scriptingEnvironment.getLuaStateForThreadID(omp_get_thread_num()) );
} }
BOOST_FOREACH(ExtractionWay & w, waysToParse) { BOOST_FOREACH(ExtractionWay & w, waysToParse) {

View File

@ -78,6 +78,8 @@ ScriptingEnvironment::ScriptingEnvironment(const char * fileName) {
.def_readwrite("ignore_in_grid", &ExtractionWay::ignoreInGrid) .def_readwrite("ignore_in_grid", &ExtractionWay::ignoreInGrid)
.def_readwrite("tags", &ExtractionWay::keyVals) .def_readwrite("tags", &ExtractionWay::keyVals)
.def_readwrite("direction", &ExtractionWay::direction) .def_readwrite("direction", &ExtractionWay::direction)
.def_readwrite("forward_mode", &ExtractionWay::forward_mode)
.def_readwrite("backward_mode", &ExtractionWay::backward_mode)
.enum_("constants") .enum_("constants")
[ [
luabind::value("notSure", 0), luabind::value("notSure", 0),

View File

@ -24,11 +24,12 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "../typedefs.h" #include "../typedefs.h"
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, const TravelMode _mode) : node(no), nameID(na), durationOfSegment(dur), turnInstruction(tu), mode(_mode) { }
NodeID node; NodeID node;
unsigned nameID; unsigned nameID;
unsigned durationOfSegment; unsigned durationOfSegment;
short turnInstruction; short turnInstruction;
TravelMode mode;
}; };
struct RawRouteData { struct RawRouteData {

View File

@ -101,7 +101,7 @@ public:
} }
} }
inline void UnpackPath(const std::vector<NodeID> & packedPath, std::vector<_PathData> & unpackedPath) const { inline void UnpackPath(const std::vector<NodeID> & packedPath, std::vector<_PathData> & unpackedPath) const {
const unsigned sizeOfPackedPath = packedPath.size(); const unsigned sizeOfPackedPath = packedPath.size();
std::stack<std::pair<NodeID, NodeID> > recursionStack; std::stack<std::pair<NodeID, NodeID> > recursionStack;
@ -144,7 +144,7 @@ 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->getTurnInstructionFromEdgeID(ed.id), ed.distance, _queryData.nodeHelpDesk->getModeFromEdgeID(ed.id)) );
} }
} }
} }
@ -158,9 +158,12 @@ public:
edge = recursionStack.top(); edge = recursionStack.top();
recursionStack.pop(); recursionStack.pop();
typename QueryDataT::Graph::EdgeIterator smallestEdge = SPECIAL_EDGEID; typename QueryDataT::Graph::EdgeIterator smallestEdge = SPECIAL_EDGEID;
int smallestWeight = INT_MAX; int smallestWeight = INT_MAX;
for(typename QueryDataT::Graph::EdgeIterator eit = _queryData.graph->BeginEdges(edge.first);eit < _queryData.graph->EndEdges(edge.first);++eit){ for(typename QueryDataT::Graph::EdgeIterator eit = _queryData.graph->BeginEdges(edge.first);eit < _queryData.graph->EndEdges(edge.first);++eit){
const int weight = _queryData.graph->GetEdgeData(eit).distance; const int weight = _queryData.graph->GetEdgeData(eit).distance;
if(_queryData.graph->GetTarget(eit) == edge.second && weight < smallestWeight && _queryData.graph->GetEdgeData(eit).forward){ if(_queryData.graph->GetTarget(eit) == edge.second && weight < smallestWeight && _queryData.graph->GetEdgeData(eit).forward){
smallestEdge = eit; smallestEdge = eit;

View File

@ -69,7 +69,7 @@ public:
middle1 = UINT_MAX; middle1 = UINT_MAX;
middle2 = UINT_MAX; middle2 = UINT_MAX;
//insert new starting nodes into forward heap, adjusted by previous distances. //insert new starting nodes into forward heap, adjusted by previous distances.
if(searchFrom1stStartNode) { if(searchFrom1stStartNode) {
forward_heap1.Insert(phantomNodePair.startPhantom.edgeBasedNode, -phantomNodePair.startPhantom.weight1, phantomNodePair.startPhantom.edgeBasedNode); forward_heap1.Insert(phantomNodePair.startPhantom.edgeBasedNode, -phantomNodePair.startPhantom.weight1, phantomNodePair.startPhantom.edgeBasedNode);
@ -165,7 +165,7 @@ public:
if(*(packedPath1.end()-1) != *(temporaryPackedPath1.begin())) { if(*(packedPath1.end()-1) != *(temporaryPackedPath1.begin())) {
packedPath1.swap(packedPath2); packedPath1.swap(packedPath2);
std::swap(distance1, distance2); std::swap(distance1, distance2);
} }
} }
} }
packedPath1.insert(packedPath1.end(), temporaryPackedPath1.begin(), temporaryPackedPath1.end()); packedPath1.insert(packedPath1.end(), temporaryPackedPath1.begin(), temporaryPackedPath1.end());
@ -185,9 +185,17 @@ public:
if(distance1 > distance2){ if(distance1 > distance2){
std::swap(packedPath1, packedPath2); std::swap(packedPath1, packedPath2);
} }
// set mode of first instruction
// if the best route started from the opposite edge, use mode2 rather than mode1
if( packedPath1.front() == phantomNodesVector[0].startPhantom.edgeBasedNode+1 ) {
phantomNodesVector[0].startPhantom.mode1 = phantomNodesVector[0].startPhantom.mode2;
}
remove_consecutive_duplicates_from_vector(packedPath1); remove_consecutive_duplicates_from_vector(packedPath1);
super::UnpackPath(packedPath1, rawRouteData.computedShortestPath); super::UnpackPath(packedPath1, rawRouteData.computedShortestPath);
rawRouteData.lengthOfShortestPath = std::min(distance1, distance2); rawRouteData.lengthOfShortestPath = std::min(distance1, distance2);
return; return;
} }
}; };

View File

@ -21,6 +21,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "QueryObjectsStorage.h" #include "QueryObjectsStorage.h"
#include "../../Util/GraphLoader.h" #include "../../Util/GraphLoader.h"
#include "../../DataStructures/QueryEdge.h"
#include "../../DataStructures/StaticGraph.h"
QueryObjectsStorage::QueryObjectsStorage(std::string hsgrPath, std::string ramIndexPath, std::string fileIndexPath, std::string nodesPath, std::string edgesPath, std::string namesPath, std::string timestampPath) { QueryObjectsStorage::QueryObjectsStorage(std::string hsgrPath, std::string ramIndexPath, std::string fileIndexPath, std::string nodesPath, std::string edgesPath, std::string namesPath, std::string timestampPath) {
INFO("loading graph data"); INFO("loading graph data");
@ -55,7 +57,7 @@ QueryObjectsStorage::QueryObjectsStorage(std::string hsgrPath, std::string ramIn
if(!nodesInStream) { ERR(nodesPath << " not found"); } if(!nodesInStream) { ERR(nodesPath << " not found"); }
std::ifstream edgesInStream(edgesPath.c_str(), std::ios::binary); std::ifstream edgesInStream(edgesPath.c_str(), std::ios::binary);
if(!edgesInStream) { ERR(edgesPath << " not found"); } if(!edgesInStream) { ERR(edgesPath << " not found"); }
nodeHelpDesk = new NodeInformationHelpDesk(ramIndexPath.c_str(), fileIndexPath.c_str(), n, checkSum); nodeHelpDesk = new NodeInformationHelpDesk(ramIndexPath.c_str(), fileIndexPath.c_str(), n, checkSum, graph);
nodeHelpDesk->initNNGrid(nodesInStream, edgesInStream); nodeHelpDesk->initNNGrid(nodesInStream, edgesInStream);
//deserialize street name list //deserialize street name list

View File

@ -26,8 +26,6 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include<string> #include<string>
#include "../../DataStructures/NodeInformationHelpDesk.h" #include "../../DataStructures/NodeInformationHelpDesk.h"
#include "../../DataStructures/QueryEdge.h"
#include "../../DataStructures/StaticGraph.h"
struct QueryObjectsStorage { struct QueryObjectsStorage {
typedef StaticGraph<QueryEdge::EdgeData> QueryGraph; typedef StaticGraph<QueryEdge::EdgeData> QueryGraph;

View File

@ -102,7 +102,8 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeL
NodeID nameID; NodeID nameID;
int length; int length;
bool isRoundabout, ignoreInGrid, isAccessRestricted, isContraFlow; bool isRoundabout, ignoreInGrid, isAccessRestricted, isContraFlow;
TravelMode mode;
for (EdgeID i=0; i<m; ++i) { for (EdgeID i=0; i<m; ++i) {
in.read((char*)&source, sizeof(unsigned)); in.read((char*)&source, sizeof(unsigned));
in.read((char*)&target, sizeof(unsigned)); in.read((char*)&target, sizeof(unsigned));
@ -115,6 +116,7 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeL
in.read((char*)&ignoreInGrid, sizeof(bool)); in.read((char*)&ignoreInGrid, sizeof(bool));
in.read((char*)&isAccessRestricted, sizeof(bool)); in.read((char*)&isAccessRestricted, sizeof(bool));
in.read((char*)&isContraFlow, sizeof(bool)); in.read((char*)&isContraFlow, sizeof(bool));
in.read((char*)&mode, sizeof(TravelMode));
GUARANTEE(length > 0, "loaded null length edge" ); GUARANTEE(length > 0, "loaded null length edge" );
GUARANTEE(weight > 0, "loaded null weight"); GUARANTEE(weight > 0, "loaded null weight");
@ -151,7 +153,7 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeL
std::swap(forward, backward); std::swap(forward, backward);
} }
EdgeT inputEdge(source, target, nameID, weight, forward, backward, type, isRoundabout, ignoreInGrid, isAccessRestricted, isContraFlow ); EdgeT inputEdge(source, target, nameID, weight, forward, backward, type, isRoundabout, ignoreInGrid, isAccessRestricted, isContraFlow, mode );
edgeList.push_back(inputEdge); edgeList.push_back(inputEdge);
} }
std::sort(edgeList.begin(), edgeList.end()); std::sort(edgeList.begin(), edgeList.end());
@ -367,7 +369,6 @@ unsigned readHSGRFromStream(std::istream &in, std::vector<NodeT>& nodeList, std:
in.read((char*) &numberOfEdges, sizeof(unsigned)); in.read((char*) &numberOfEdges, sizeof(unsigned));
edgeList.resize(numberOfEdges); edgeList.resize(numberOfEdges);
in.read((char*) &(edgeList[0]), numberOfEdges*sizeof(EdgeT)); in.read((char*) &(edgeList[0]), numberOfEdges*sizeof(EdgeT));
return numberOfNodes; return numberOfNodes;
} }

View File

@ -255,6 +255,7 @@ int main (int argc, char *argv[]) {
ERR("Failed at edges of node " << node << " of " << numberOfNodes); ERR("Failed at edges of node " << node << " of " << numberOfNodes);
} }
//Serialize edges //Serialize edges
//INFO( "createHierachy write, i: " << usedEdgeCounter << ", mode: " << (long)currentEdge.data.mode );
edgeOutFile.write((char*) &currentEdge, sizeof(StaticGraph<EdgeData>::_StrEdge)); edgeOutFile.write((char*) &currentEdge, sizeof(StaticGraph<EdgeData>::_StrEdge));
++edge; ++edge;
++usedEdgeCounter; ++usedEdgeCounter;

View File

@ -1,10 +1,14 @@
@routing @bicycle @mode @routing @bicycle @mode
Feature: Bike - Mode flag Feature: Bike - Mode flag
# bicycle modes:
# 1 bike
# 2 ferry
# 3 push
Background: Background:
Given the profile "bicycle" Given the profile "bicycle"
@todo
Scenario: Bike - Mode when using a ferry Scenario: Bike - Mode when using a ferry
Given the node map Given the node map
| a | b | | | a | b | |
@ -17,15 +21,14 @@ Feature: Bike - Mode flag
| cd | primary | | | | cd | primary | | |
When I route I should get When I route I should get
| from | to | route | turns | modes | | from | to | route | turns | modes |
| a | d | ab,bc,cd | head,right,left, destination | bike,ferry,bike | | a | d | ab,bc,cd | head,right,left,destination | 1,2,1 |
| d | a | cd,bc,ab | head,right,left, destination | bike,ferry,bike | | d | a | cd,bc,ab | head,right,left,destination | 1,2,1 |
| c | a | bc,ab | head,left,destination | ferry,bike | | c | a | bc,ab | head,left,destination | 2,1 |
| d | b | cd,bc | head,right,destination | bike,ferry | | d | b | cd,bc | head,right,destination | 1,2 |
| a | c | ab,bc | head,right,destination | bike,ferry | | a | c | ab,bc | head,right,destination | 1,2 |
| b | d | bc,cd | head,left,destination | ferry,bike | | b | d | bc,cd | head,left,destination | 2,1 |
@todo
Scenario: Bike - Mode when pushing bike against oneways Scenario: Bike - Mode when pushing bike against oneways
Given the node map Given the node map
| a | b | | | a | b | |
@ -38,15 +41,14 @@ Feature: Bike - Mode flag
| cd | primary | | | cd | primary | |
When I route I should get When I route I should get
| from | to | route | turns | modes | | from | to | route | turns | modes |
| a | d | ab,bc,cd | head,right,left,destination | bike,push,bike | | a | d | ab,bc,cd | head,right,left,destination | 1,1,1 |
| d | a | cd,bc,ab | head,right,left,destination | bike,push,bike | | d | a | cd,bc,ab | head,right,left,destination | 1,3,1 |
| c | a | bc,ab | head,left,destination | push,bike | | c | a | bc,ab | head,left,destination | 3,1 |
| d | b | cd,bc | head,right,destination | bike,push | | d | b | cd,bc | head,right,destination | 1,3 |
| a | c | ab,bc | head,right,destination | bike,push | | a | c | ab,bc | head,right,destination | 1,1 |
| b | d | bc,cd | head,left,destination | push,bike | | b | d | bc,cd | head,left,destination | 1,1 |
@todo
Scenario: Bike - Mode when pushing on pedestrain streets Scenario: Bike - Mode when pushing on pedestrain streets
Given the node map Given the node map
| a | b | | | a | b | |
@ -59,15 +61,14 @@ Feature: Bike - Mode flag
| cd | primary | | cd | primary |
When I route I should get When I route I should get
| from | to | route | turns | modes | | from | to | route | turns | modes |
| a | d | ab,bc,cd | head,right,left,destination | bike,push,bike | | a | d | ab,bc,cd | head,right,left,destination | 1,3,1 |
| d | a | cd,bc,ab | head,right,left,destination | bike,push,bike | | d | a | cd,bc,ab | head,right,left,destination | 1,3,1 |
| c | a | bc,ab | head,left,destination | push,bike | | c | a | bc,ab | head,left,destination | 3,1 |
| d | b | cd,bc | head,right,destination | bike,push | | d | b | cd,bc | head,right,destination | 1,3 |
| a | c | ab,bc | head,right,destination | bike,push | | a | c | ab,bc | head,right,destination | 1,3 |
| b | d | bc,cd | head,left,destination | push,bike | | b | d | bc,cd | head,left,destination | 3,1 |
@todo
Scenario: Bike - Mode when pushing on pedestrain areas Scenario: Bike - Mode when pushing on pedestrain areas
Given the node map Given the node map
| a | b | | | | a | b | | |
@ -80,10 +81,10 @@ Feature: Bike - Mode flag
| df | primary | | | df | primary | |
When I route I should get When I route I should get
| from | to | route | modes | | from | to | route | modes |
| a | f | ab,bcd,df | bike,push,bike | | a | f | ab,bcd,df | 1,3,1 |
| f | a | df,bcd,ab | bike,push,bike | | f | a | df,bcd,ab | 1,3,1 |
| d | a | bcd,ab | push,bike | | d | a | bcd,ab | 3,1 |
| f | b | df,bcd | bike,push | | f | b | df,bcd | 1,3 |
| a | d | ab,bcd | bike,push | | a | d | ab,bcd | 1,3 |
| b | f | bcd,df | push,bike | | b | f | bcd,df | 3,1 |

View File

@ -98,11 +98,11 @@ Feature: Bike - Accessability of different way types
| cd | primary | | | cd | primary | |
When I route I should get When I route I should get
| from | to | route | turns | | from | to | route | turns |
| a | d | ab,bc,cd | head,right,left,destination | | a | d | ab,bc,cd | head,right,left,destination |
| d | a | cd,bc,ab | head,enter_contraflow,leave_contraflow,destination | | d | a | cd,bc,ab | head,right,left,destination |
| c | a | bc,ab | head,leave_contraflow,destination | | c | a | bc,ab | head,left,destination |
| d | b | cd,bc | head,enter_contraflow,destination | | d | b | cd,bc | head,right,destination |
@todo @todo
Scenario: Bike - Instructions when pushing bike on footway/pedestrian, etc. Scenario: Bike - Instructions when pushing bike on footway/pedestrian, etc.
@ -117,8 +117,22 @@ Feature: Bike - Accessability of different way types
| cd | primary | | cd | primary |
When I route I should get When I route I should get
| from | to | route | turns | | from | to | route | turns |
| a | d | ab,bc,cd | head,right,left,destination | | a | d | ab,bc,cd | head,right,left,destination |
| d | a | cd,bc,ab | head,enter_contraflow,leave_contraflow,destination | | d | a | cd,bc,ab | head,right,left,destination |
| c | a | bc,ab | head,leave_contraflow,destination | | c | a | bc,ab | head,left,destination |
| d | b | cd,bc | head,enter_contraflow,destination | | d | b | cd,bc | head,right,destination |
Scenario: Bike - Push bikes on pedestrian areas
Given the node map
| a | b | c | d |
And the ways
| nodes | highway |
| ab | primary |
| bc | pedestrian |
| cd | primary |
When I route I should get
| from | to | route | turns |
| a | d | ab,bc,cd | head,straight,straight,destination |

View File

@ -1,26 +1,82 @@
@routing @testbot @mode @routing @testbot @mode
Feature: Testbot - Mode flag Feature: Testbot - Mode flag
# testbot modes:
# 1 normal
# 2 route
# 3 river downstream
# 4 river upstream
Background: Background:
Given the profile "testbot" Given the profile "testbot"
@todo Scenario: Testbot - Mode for routes
Scenario: Bike - Mode Given the node map
Given the node map | a | b | | | |
| a | b | | | | c | d | e | f |
| | c | d |
And the ways And the ways
| nodes | highway | route | duration | | nodes | highway | route | duration |
| ab | primary | | | | ab | primary | | |
| bc | | ferry | 0:01 | | bc | | ferry | 0:01 |
| cd | primary | | | | cd | primary | | |
| de | primary | | |
| ef | primary | | |
When I route I should get When I route I should get
| from | to | route | turns | modes | | from | to | route | turns | modes |
| a | d | ab,bc,cd | head,right,left,destination | bot,ferry,bot | | a | d | ab,bc,cd | head,right,left,destination | 1,2,1 |
| d | a | cd,bc,ab | head,right left,destination | bot,ferry,bot | | d | a | cd,bc,ab | head,right,left,destination | 1,2,1 |
| c | a | bc,ab | head,left,destination | ferry,bot | | c | a | bc,ab | head,left,destination | 2,1 |
| d | b | cd,bc | head,right,destination | bot,ferry | | d | b | cd,bc | head,right,destination | 1,2 |
| a | c | ab,bc | head,right,destination | bot,ferry | | a | c | ab,bc | head,right,destination | 1,2 |
| b | d | bc,cd | head,left,destination | ferry,bot | | b | d | bc,cd | head,left,destination | 2,1 |
| a | f | ab,bc,cd,de,ef | head,right,left,straight,straight,destination | 1,2,1,1,1 |
Scenario: Testbot - Modes for each direction
Given the node map
| | | | | | | d |
| | | | | | 2 | |
| | | | | 6 | | 5 |
| a | 0 | b | c | | | |
| | | | | 4 | | 1 |
| | | | | | 3 | |
| | | | | | | e |
And the ways
| nodes | highway | oneway |
| abc | primary | |
| cd | primary | yes |
| ce | river | |
| de | primary | |
When I route I should get
| from | to | route | modes |
| 0 | 1 | abc,ce,de | 1,3,1 |
| 1 | 0 | de,ce,abc | 1,4,1 |
| 0 | 2 | abc,cd | 1,1 |
| 2 | 0 | cd,de,ce,abc | 1,1,4,1 |
| 0 | 3 | abc,ce | 1,3 |
| 3 | 0 | ce,abc | 4,1 |
| 4 | 3 | ce | 3 |
| 3 | 4 | ce | 4 |
| 3 | 1 | ce,de | 3,1 |
| 1 | 3 | de,ce | 1,4 |
| a | e | abc,ce | 1,3 |
| e | a | ce,abc | 4,1 |
| a | d | abc,cd | 1,1 |
| d | a | de,ce,abc | 1,4,1 |
Scenario: Testbot - Modes in each direction (simple)
Given the node map
| | 0 | 1 | |
| a | | | b |
And the ways
| nodes | highway | oneway |
| ab | river | |
When I route I should get
| from | to | route | modes |
| 0 | 1 | ab | 3 |
| 1 | 0 | ab | 4 |

View File

@ -177,6 +177,8 @@ function way_function (way)
local area = way.tags:Find("area") local area = way.tags:Find("area")
local foot = way.tags:Find("foot") local foot = way.tags:Find("foot")
local surface = way.tags:Find("surface") local surface = way.tags:Find("surface")
local foot_forward = way.tags:Find("foot:forward")
local foot_backward = way.tags:Find("foot:backward")
-- name -- name
if "" ~= ref and "" ~= name then if "" ~= ref and "" ~= name then
@ -189,7 +191,10 @@ function way_function (way)
way.name = "{highway:"..highway.."}" -- if no name exists, use way type way.name = "{highway:"..highway.."}" -- if no name exists, use way type
-- this encoding scheme is excepted to be a temporary solution -- this encoding scheme is excepted to be a temporary solution
end end
way.forward_mode = 1
way.backward_mode = 1
-- speed -- speed
if route_speeds[route] then if route_speeds[route] then
-- ferries (doesn't cover routes tagged using relations) -- ferries (doesn't cover routes tagged using relations)
@ -200,6 +205,8 @@ function way_function (way)
else else
way.speed = route_speeds[route] way.speed = route_speeds[route]
end end
way.forward_mode = 2
way.backward_mode = 2
elseif railway and platform_speeds[railway] then elseif railway and platform_speeds[railway] then
-- railway platforms (old tagging scheme) -- railway platforms (old tagging scheme)
way.speed = platform_speeds[railway] way.speed = platform_speeds[railway]
@ -224,16 +231,30 @@ function way_function (way)
else else
-- biking not allowed, maybe we can push our bike? -- biking not allowed, maybe we can push our bike?
-- essentially requires pedestrian profiling, for example foot=no mean we can't push a bike -- essentially requires pedestrian profiling, for example foot=no mean we can't push a bike
-- TODO: if we can push, the way should be marked as pedestrion mode, but there's no way to do it yet from lua..
if foot ~= 'no' then if foot ~= 'no' then
if pedestrian_speeds[highway] then if pedestrian_speeds[highway] then
-- pedestrian-only ways and areas -- pedestrian-only ways and areas
way.speed = pedestrian_speeds[highway] way.speed = pedestrian_speeds[highway]
way.forward_mode = 3
way.backward_mode = 3
elseif man_made and man_made_speeds[man_made] then elseif man_made and man_made_speeds[man_made] then
-- man made structures -- man made structures
way.speed = man_made_speeds[man_made] way.speed = man_made_speeds[man_made]
way.forward_mode = 3
way.backward_mode = 3
elseif foot == 'yes' then elseif foot == 'yes' then
way.speed = walking_speed way.speed = walking_speed
way.forward_mode = 3
way.backward_mode = 3
elseif foot_forward == 'yes' then
way.speed = walking_speed
way.forward_mode = 3
way.backward_mode = 0
elseif foot_backward == 'yes' then
way.speed = 0
way.backward_speed = walking_speed
way.forward_mode = 0
way.backward_mode = 3
end end
end end
end end
@ -286,14 +307,15 @@ function way_function (way)
if junction ~= "roundabout" then if junction ~= "roundabout" then
if way.direction == Way.oneway then if way.direction == Way.oneway then
way.backward_speed = walking_speed way.backward_speed = walking_speed
way.backward_mode = 3
elseif way.direction == Way.opposite then elseif way.direction == Way.opposite then
way.backward_speed = walking_speed way.backward_speed = walking_speed
way.backward_mode = 3
way.speed = way.speed way.speed = way.speed
end end
end end
end end
if way.backward_speed == way.speed then if way.backward_speed == way.speed then
-- TODO: no way yet to mark a way as pedestrian mode if forward/backward speeds are equal
way.direction = Way.bidirectional way.direction = Way.bidirectional
end end
end end
@ -336,8 +358,6 @@ function way_function (way)
way.backward_speed = maxspeed_backward way.backward_speed = maxspeed_backward
end end
way.type = 1 way.type = 1
return 1 return 1
end end

View File

@ -6,6 +6,12 @@
-- Secondary road: 18km/h = 18000m/3600s = 100m/20s -- Secondary road: 18km/h = 18000m/3600s = 100m/20s
-- Tertiary road: 12km/h = 12000m/3600s = 100m/30s -- Tertiary road: 12km/h = 12000m/3600s = 100m/30s
-- modes:
-- 1: normal
-- 2: route
-- 3: river downstream
-- 4: river upstream
speed_profile = { speed_profile = {
["primary"] = 36, ["primary"] = 36,
["secondary"] = 18, ["secondary"] = 18,
@ -23,6 +29,14 @@ ignore_areas = true -- future feature
traffic_signal_penalty = 7 -- seconds traffic_signal_penalty = 7 -- seconds
u_turn_penalty = 20 u_turn_penalty = 20
modes = { "bot", "ferry", "downstream", "upstream" }
function get_modes(vector)
for i,v in ipairs(modes) do
vector:Add(v)
end
end
function limit_speed(speed, limits) function limit_speed(speed, limits)
-- don't use ipairs(), since it stops at the first nil value -- don't use ipairs(), since it stops at the first nil value
for i=1, #limits do for i=1, #limits do
@ -56,10 +70,14 @@ function way_function (way)
local maxspeed_forward = tonumber(way.tags:Find( "maxspeed:forward")) local maxspeed_forward = tonumber(way.tags:Find( "maxspeed:forward"))
local maxspeed_backward = tonumber(way.tags:Find( "maxspeed:backward")) local maxspeed_backward = tonumber(way.tags:Find( "maxspeed:backward"))
way.forward_mode = 1
way.backward_mode = 1
way.name = name way.name = name
if route ~= nil and durationIsValid(duration) then if route ~= nil and durationIsValid(duration) then
way.duration = math.max( 1, parseDuration(duration) ) way.duration = math.max( 1, parseDuration(duration) )
way.forward_mode = 2
way.backward_mode = 2
else else
local speed_forw = speed_profile[highway] or speed_profile['default'] local speed_forw = speed_profile[highway] or speed_profile['default']
local speed_back = speed_forw local speed_back = speed_forw
@ -68,7 +86,9 @@ function way_function (way)
local temp_speed = speed_forw; local temp_speed = speed_forw;
speed_forw = temp_speed*1.5 speed_forw = temp_speed*1.5
speed_back = temp_speed/1.5 speed_back = temp_speed/1.5
end way.forward_mode = 3
way.backward_mode = 4
end
if maxspeed_forward ~= nil and maxspeed_forward > 0 then if maxspeed_forward ~= nil and maxspeed_forward > 0 then
speed_forw = maxspeed_forward speed_forw = maxspeed_forward