mode flags
This commit is contained in:
parent
67addfdb37
commit
42b7312cd2
@ -11,7 +11,7 @@ file(GLOB PrepareGlob Contractor/*.cpp)
|
||||
set(PrepareSources createHierarchy.cpp ${PrepareGlob})
|
||||
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})
|
||||
add_executable(osrm-routed ${RoutedSources})
|
||||
set_target_properties(osrm-routed PROPERTIES COMPILE_FLAGS -DROUTED)
|
||||
|
||||
@ -26,6 +26,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#include "Contractor.h"
|
||||
#include "TravelMode.h"
|
||||
|
||||
class ContractionCleanup {
|
||||
private:
|
||||
@ -64,6 +65,7 @@ public:
|
||||
bool shortcut:1;
|
||||
bool forward:1;
|
||||
bool backward:1;
|
||||
TravelMode mode;
|
||||
} data;
|
||||
bool operator<( const Edge& right ) const {
|
||||
if ( source != right.source )
|
||||
|
||||
@ -74,6 +74,7 @@ EdgeBasedGraphFactory::EdgeBasedGraphFactory(int nodes, std::vector<NodeBasedEdg
|
||||
edge.data.isAccessRestricted = i->isAccessRestricted();
|
||||
edge.data.edgeBasedNodeID = edges.size();
|
||||
edge.data.contraFlow = i->isContraFlow();
|
||||
edge.data.mode = i->mode();
|
||||
edges.push_back( edge );
|
||||
if( edge.data.backward ) {
|
||||
std::swap( edge.source, edge.target );
|
||||
@ -147,6 +148,7 @@ void EdgeBasedGraphFactory::InsertEdgeBasedNode(
|
||||
currentNode.id = data.edgeBasedNodeID;
|
||||
currentNode.ignoreInGrid = data.ignoreInGrid;
|
||||
currentNode.weight = data.distance;
|
||||
currentNode.mode = data.mode;
|
||||
edgeBasedNodes.push_back(currentNode);
|
||||
}
|
||||
|
||||
@ -274,7 +276,9 @@ void EdgeBasedGraphFactory::Run(const char * originalEdgeDataFilename, lua_State
|
||||
distance += speedProfile.trafficSignalPenalty;
|
||||
}
|
||||
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)
|
||||
distance += speedProfile.uTurnPenalty;
|
||||
// if(!edgeData1.isAccessRestricted && edgeData2.isAccessRestricted) {
|
||||
@ -283,11 +287,10 @@ void EdgeBasedGraphFactory::Run(const char * originalEdgeDataFilename, lua_State
|
||||
// }
|
||||
distance += penalty;
|
||||
|
||||
|
||||
//distance += heightPenalty;
|
||||
//distance += ComputeTurnPenalty(u, v, w);
|
||||
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);
|
||||
++numberOfOriginalEdges;
|
||||
|
||||
@ -326,7 +329,7 @@ void EdgeBasedGraphFactory::Run(const char * originalEdgeDataFilename, lua_State
|
||||
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]);
|
||||
|
||||
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 & data2 = _nodeBasedGraph->GetEdgeData(edge2);
|
||||
|
||||
if(!data1.contraFlow && data2.contraFlow) {
|
||||
return TurnInstructions.EnterAgainstAllowedDirection;
|
||||
}
|
||||
if(data1.contraFlow && !data2.contraFlow) {
|
||||
return TurnInstructions.LeaveAgainstAllowedDirection;
|
||||
}
|
||||
contraflow = data2.contraFlow;
|
||||
|
||||
//roundabouts need to be handled explicitely
|
||||
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( (data1.nameID == data2.nameID) && (0 != data1.nameID)) {
|
||||
//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) && (data1.mode == data2.mode) && (0 != data1.nameID)) {
|
||||
return TurnInstructions.NoTurn;
|
||||
}
|
||||
if( (data1.nameID == data2.nameID) && (0 == data1.nameID) && (_nodeBasedGraph->GetOutDegree(v) <= 2) ) {
|
||||
|
||||
@ -77,6 +77,7 @@ public:
|
||||
NodeID nameID;
|
||||
unsigned weight:31;
|
||||
bool ignoreInGrid:1;
|
||||
TravelMode mode;
|
||||
};
|
||||
|
||||
struct SpeedProfileProperties{
|
||||
@ -99,6 +100,7 @@ private:
|
||||
bool roundabout:1;
|
||||
bool ignoreInGrid:1;
|
||||
bool contraFlow:1;
|
||||
TravelMode mode;
|
||||
};
|
||||
|
||||
struct _EdgeBasedEdgeData {
|
||||
@ -108,6 +110,7 @@ private:
|
||||
bool forward;
|
||||
bool backward;
|
||||
TurnInstruction turnInstruction;
|
||||
TravelMode mode;
|
||||
};
|
||||
|
||||
typedef DynamicGraph< _NodeBasedEdgeData > _NodeBasedDynamicGraph;
|
||||
@ -147,7 +150,7 @@ public:
|
||||
void GetEdgeBasedEdges( DeallocatingVector< EdgeBasedEdge >& edges );
|
||||
void GetEdgeBasedNodes( DeallocatingVector< EdgeBasedNode> & nodes);
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
@ -22,16 +22,18 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#define GRIDEDGE_H_
|
||||
|
||||
#include "Coordinate.h"
|
||||
#include "TravelMode.h"
|
||||
|
||||
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() : edgeBasedNode(UINT_MAX), nameID(UINT_MAX), weight(INT_MAX), belongsToTinyComponent(false) {}
|
||||
_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), mode(0) {}
|
||||
NodeID edgeBasedNode;
|
||||
NodeID nameID;
|
||||
int weight;
|
||||
_Coordinate startCoord;
|
||||
_Coordinate targetCoord;
|
||||
bool belongsToTinyComponent;
|
||||
TravelMode mode;
|
||||
|
||||
bool operator< ( const _GridEdge& right) const {
|
||||
return edgeBasedNode < right.edgeBasedNode;
|
||||
|
||||
@ -23,6 +23,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "TravelMode.h"
|
||||
|
||||
class NodeBasedEdge {
|
||||
public:
|
||||
|
||||
@ -40,8 +42,8 @@ public:
|
||||
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) :
|
||||
_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);}; }
|
||||
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), _mode(mode) { if(ty < 0) {ERR("Type: " << ty);}; }
|
||||
|
||||
NodeID target() const {return _target; }
|
||||
NodeID source() const {return _source; }
|
||||
@ -56,6 +58,7 @@ public:
|
||||
bool ignoreInGrid() const { return _ignoreInGrid; }
|
||||
bool isAccessRestricted() const { return _accessRestricted; }
|
||||
bool isContraFlow() const { return _contraFlow; }
|
||||
TravelMode mode() const { return _mode; }
|
||||
|
||||
NodeID _source;
|
||||
NodeID _target;
|
||||
@ -68,11 +71,12 @@ public:
|
||||
bool _ignoreInGrid;
|
||||
bool _accessRestricted;
|
||||
bool _contraFlow;
|
||||
TravelMode _mode;
|
||||
|
||||
private:
|
||||
/** Default constructor. target and weight are set to 0.*/
|
||||
NodeBasedEdge() :
|
||||
_source(0), _target(0), _name(0), _weight(0), forward(0), backward(0), _type(0), _roundabout(false), _ignoreInGrid(false), _accessRestricted(false), _contraFlow(false) { assert(false); } //shall not be used.
|
||||
_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; }
|
||||
NodeID id() const { return m_edgeID; }
|
||||
bool isBackward() const { return m_backward; }
|
||||
bool isForward() const { return m_forward; }
|
||||
bool isForward() const { return m_forward; }
|
||||
private:
|
||||
NodeID m_source;
|
||||
NodeID m_target;
|
||||
|
||||
113
DataStructures/NNGrid.cpp
Normal file
113
DataStructures/NNGrid.cpp
Normal 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;
|
||||
}
|
||||
|
||||
@ -51,37 +51,31 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#include "StaticGraph.h"
|
||||
#include "TimingUtil.h"
|
||||
#include "../Algorithms/Bresenham.h"
|
||||
#include "QueryEdge.h"
|
||||
|
||||
namespace NNGrid{
|
||||
class NodeInformationHelpDesk;
|
||||
class QueryGraph;
|
||||
|
||||
static boost::thread_specific_ptr<std::ifstream> localStream;
|
||||
|
||||
template<bool WriteAccess = false>
|
||||
|
||||
class NNGrid {
|
||||
public:
|
||||
NNGrid() /*: cellCache(500), fileCache(500)*/ {
|
||||
ramIndexTable.resize((1024*1024), std::numeric_limits<uint64_t>::max());
|
||||
}
|
||||
|
||||
NNGrid(const char* rif, const char* _i) {
|
||||
if(WriteAccess) {
|
||||
ERR("Not available in Write mode");
|
||||
}
|
||||
NNGrid() : nodeHelpDesk(NULL) {}
|
||||
|
||||
|
||||
NNGrid(const char* rif, const char* _i, NodeInformationHelpDesk* _nodeHelpDesk, StaticGraph<QueryEdge::EdgeData>* g) : nodeHelpDesk(_nodeHelpDesk), graph(g) {
|
||||
nodeHelpDesk = _nodeHelpDesk;
|
||||
iif = std::string(_i);
|
||||
|
||||
ramIndexTable.resize((1024*1024), std::numeric_limits<uint64_t>::max());
|
||||
ramInFile.open(rif, std::ios::in | std::ios::binary);
|
||||
if(!ramInFile) { ERR(rif << " not found"); }
|
||||
|
||||
}
|
||||
|
||||
|
||||
~NNGrid() {
|
||||
if(ramInFile.is_open()) ramInFile.close();
|
||||
|
||||
#ifndef ROUTED
|
||||
if (WriteAccess) {
|
||||
entries.clear();
|
||||
}
|
||||
#endif
|
||||
if(localStream.get() && localStream->is_open()) {
|
||||
localStream->close();
|
||||
}
|
||||
@ -106,7 +100,7 @@ public:
|
||||
int slon = edge.lon1;
|
||||
int tlat = 100000*lat2y(edge.lat2/100000.);
|
||||
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() ) {
|
||||
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);
|
||||
}
|
||||
|
||||
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 FindPhantomNodeForCoordinate( const _Coordinate & location, PhantomNode & resultNode, const unsigned zoomLevel);
|
||||
|
||||
bool FindRoutingStarts(const _Coordinate& start, const _Coordinate& target, PhantomNodes & routingStarts, unsigned zoomLevel) {
|
||||
routingStarts.Reset();
|
||||
@ -282,7 +193,7 @@ public:
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
protected:
|
||||
inline unsigned GetCellIndexFromRAMAndFileIndex(const unsigned ramIndex, const unsigned fileIndex) const {
|
||||
unsigned lineBase = ramIndex/1024;
|
||||
lineBase = lineBase*32*32768;
|
||||
@ -589,14 +500,30 @@ private:
|
||||
std::ofstream indexOutFile;
|
||||
stxxl::vector<GridEntry> entries;
|
||||
#endif
|
||||
NodeInformationHelpDesk* nodeHelpDesk;
|
||||
std::vector<uint64_t> ramIndexTable; //8 MB for first level index in RAM
|
||||
std::string iif;
|
||||
bool writeAccess;
|
||||
StaticGraph<QueryEdge::EdgeData>* graph;
|
||||
// LRUCache<int,std::vector<unsigned> > cellCache;
|
||||
// LRUCache<int,std::vector<_Edge> > fileCache;
|
||||
};
|
||||
}
|
||||
|
||||
typedef NNGrid::NNGrid<false> ReadOnlyGrid;
|
||||
typedef NNGrid::NNGrid<true > WritableGrid;
|
||||
class ReadOnlyGrid : public NNGrid {
|
||||
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_ */
|
||||
|
||||
@ -32,11 +32,14 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#include "NNGrid.h"
|
||||
#include "PhantomNodes.h"
|
||||
#include "NodeCoords.h"
|
||||
#include "TravelMode.h"
|
||||
|
||||
class QueryGraph;
|
||||
|
||||
class NodeInformationHelpDesk : boost::noncopyable{
|
||||
public:
|
||||
NodeInformationHelpDesk(const char* ramIndexInput, const char* fileIndexInput, const unsigned _numberOfNodes, const unsigned crc) : numberOfNodes(_numberOfNodes), checkSum(crc) {
|
||||
readOnlyGrid = new ReadOnlyGrid(ramIndexInput,fileIndexInput);
|
||||
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, this, graph);
|
||||
assert(0 == coordinateVector.size());
|
||||
}
|
||||
|
||||
@ -64,6 +67,7 @@ public:
|
||||
origEdgeData_viaNode.resize(numberOfOrigEdges);
|
||||
origEdgeData_nameID.resize(numberOfOrigEdges);
|
||||
origEdgeData_turnInstruction.resize(numberOfOrigEdges);
|
||||
origEdgeData_mode.resize(numberOfOrigEdges);
|
||||
|
||||
OriginalEdgeData deserialized_originalEdgeData;
|
||||
for(unsigned i = 0; i < numberOfOrigEdges; ++i) {
|
||||
@ -71,6 +75,7 @@ public:
|
||||
origEdgeData_viaNode[i] = deserialized_originalEdgeData.viaNode;
|
||||
origEdgeData_nameID[i] = deserialized_originalEdgeData.nameID;
|
||||
origEdgeData_turnInstruction[i] = deserialized_originalEdgeData.turnInstruction;
|
||||
origEdgeData_mode[i] = deserialized_originalEdgeData.mode;
|
||||
}
|
||||
edgesInStream.close();
|
||||
DEBUG("Loaded " << numberOfOrigEdges << " orig edges");
|
||||
@ -100,6 +105,10 @@ public:
|
||||
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 getNumberOfNodes2() const { return coordinateVector.size(); }
|
||||
|
||||
@ -128,6 +137,7 @@ private:
|
||||
std::vector<NodeID> origEdgeData_viaNode;
|
||||
std::vector<unsigned> origEdgeData_nameID;
|
||||
std::vector<TurnInstruction> origEdgeData_turnInstruction;
|
||||
std::vector<TravelMode> origEdgeData_mode;
|
||||
|
||||
ReadOnlyGrid * readOnlyGrid;
|
||||
const unsigned numberOfNodes;
|
||||
|
||||
@ -22,14 +22,17 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#define PHANTOMNODES_H_
|
||||
|
||||
#include "Coordinate.h"
|
||||
#include "TravelMode.h"
|
||||
|
||||
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;
|
||||
unsigned nodeBasedEdgeNameID;
|
||||
int weight1;
|
||||
int weight2;
|
||||
double ratio;
|
||||
TravelMode mode1;
|
||||
TravelMode mode2;
|
||||
_Coordinate location;
|
||||
void Reset() {
|
||||
edgeBasedNode = UINT_MAX;
|
||||
|
||||
@ -24,22 +24,32 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#define QUERYEDGE_H_
|
||||
|
||||
#include "TurnInstructions.h"
|
||||
#include "TravelMode.h"
|
||||
#include "../typedefs.h"
|
||||
|
||||
#include <climits>
|
||||
|
||||
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) {}
|
||||
NodeID viaNode;
|
||||
unsigned nameID;
|
||||
TurnInstruction turnInstruction;
|
||||
TravelMode mode;
|
||||
};
|
||||
|
||||
struct QueryEdge {
|
||||
NodeID source;
|
||||
NodeID target;
|
||||
struct EdgeData {
|
||||
EdgeData() :
|
||||
id(0),
|
||||
shortcut(false),
|
||||
distance(0),
|
||||
forward(false),
|
||||
backward(false)
|
||||
{}
|
||||
|
||||
NodeID id:31;
|
||||
bool shortcut:1;
|
||||
int distance:30;
|
||||
|
||||
@ -33,10 +33,11 @@ struct SegmentInformation {
|
||||
double bearing;
|
||||
TurnInstruction turnInstruction;
|
||||
bool necessary;
|
||||
SegmentInformation(const _Coordinate & loc, const NodeID nam, const double len, const unsigned dur, const TurnInstruction tInstr, const bool nec) :
|
||||
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) :
|
||||
location(loc), nameID(nam), length(len), duration(dur), bearing(0.), turnInstruction(tInstr), necessary(tInstr != 0) {}
|
||||
char mode;
|
||||
SegmentInformation(const _Coordinate & loc, const NodeID nam, const double len, const unsigned dur, const TurnInstruction tInstr, const bool nec, const char mod) :
|
||||
location(loc), nameID(nam), length(len), duration(dur), bearing(0.), turnInstruction(tInstr), necessary(nec), mode(mod) {}
|
||||
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_ */
|
||||
|
||||
26
DataStructures/TravelMode.h
Normal file
26
DataStructures/TravelMode.h
Normal 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_ */
|
||||
@ -51,19 +51,20 @@ double DescriptionFactory::GetBearing(const _Coordinate& A, const _Coordinate& B
|
||||
|
||||
void DescriptionFactory::SetStartSegment(const PhantomNode & _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) {
|
||||
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 ) {
|
||||
if(1 == pathDescription.size() && pathDescription.back().location == coordinate) {
|
||||
pathDescription.back().nameID = data.nameID;
|
||||
pathDescription.back().mode = data.mode;
|
||||
} 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) {
|
||||
|
||||
if(0 == pathDescription.size())
|
||||
return;
|
||||
|
||||
@ -170,6 +170,7 @@ void DescriptionFactory::Run(const SearchEngineT &sEngine, const unsigned zoomLe
|
||||
pathDescription.back().necessary = true;
|
||||
pathDescription.back().turnInstruction = TurnInstructions.NoTurn;
|
||||
targetPhantom.nodeBasedEdgeNameID = (pathDescription.end()-2)->nameID;
|
||||
targetPhantom.mode1 = (pathDescription.end()-2)->mode;
|
||||
// INFO("Deleting last turn instruction");
|
||||
}
|
||||
} else {
|
||||
@ -182,7 +183,8 @@ void DescriptionFactory::Run(const SearchEngineT &sEngine, const unsigned zoomLe
|
||||
pathDescription[0].turnInstruction = TurnInstructions.HeadOn;
|
||||
pathDescription[0].necessary = true;
|
||||
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 {
|
||||
pathDescription[0].duration *= startPhantom.ratio;
|
||||
|
||||
@ -312,7 +312,7 @@ public:
|
||||
unsigned prefixSumOfNecessarySegments = 0;
|
||||
roundAbout.leaveAtExit = 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.
|
||||
BOOST_FOREACH(const SegmentInformation & segment, descriptionFactory.pathDescription) {
|
||||
TurnInstruction currentInstruction = segment.turnInstruction & TurnInstructions.InverseAccessRestrictionFlag;
|
||||
@ -358,6 +358,11 @@ public:
|
||||
reply.content += "\",";
|
||||
intToString(round(segment.bearing), tmpBearing);
|
||||
reply.content += tmpBearing;
|
||||
|
||||
reply.content += ",";
|
||||
intToString(segment.mode, tmpMode);
|
||||
reply.content += tmpMode;
|
||||
|
||||
reply.content += "]";
|
||||
|
||||
segmentVector.push_back( Segment(segment.nameID, segment.length, segmentVector.size() ));
|
||||
|
||||
@ -25,6 +25,7 @@ extractor_callbacks(ec), scriptingEnvironment(se), luaState(NULL), use_turn_rest
|
||||
luaState = se.getLuaStateForThreadID(0);
|
||||
ReadUseRestrictionsSetting();
|
||||
ReadRestrictionExceptions();
|
||||
ReadModes();
|
||||
}
|
||||
|
||||
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 {
|
||||
if( 0!=status ) {
|
||||
std::cerr << "-- " << lua_tostring(L, -1) << std::endl;
|
||||
|
||||
@ -46,6 +46,7 @@ public:
|
||||
protected:
|
||||
virtual void ReadUseRestrictionsSetting();
|
||||
virtual void ReadRestrictionExceptions();
|
||||
virtual void ReadModes();
|
||||
virtual bool ShouldIgnoreRestriction(const std::string& except_tag_string) const;
|
||||
|
||||
ExtractorCallbacks* extractor_callbacks;
|
||||
@ -53,7 +54,7 @@ protected:
|
||||
lua_State* luaState;
|
||||
std::vector<std::string> restriction_exceptions;
|
||||
bool use_turn_restrictions;
|
||||
|
||||
std::vector<std::string> modes;
|
||||
};
|
||||
|
||||
#endif /* BASEPARSER_H_ */
|
||||
|
||||
@ -257,6 +257,7 @@ void ExtractionContainers::PrepareData(const std::string & outputFileName, const
|
||||
fout.write((char*)&edgeIT->ignoreInGrid, sizeof(bool));
|
||||
fout.write((char*)&edgeIT->isAccessRestricted, sizeof(bool));
|
||||
fout.write((char*)&edgeIT->isContraFlow, sizeof(bool));
|
||||
fout.write((char*)&edgeIT->mode, sizeof(unsigned char));
|
||||
}
|
||||
++usedEdgeCounter;
|
||||
++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 << "[extractor] setting number of edges ... " << std::flush;
|
||||
|
||||
std::cout << "[extractor] number of edges: " << usedEdgeCounter << std::flush;
|
||||
|
||||
fout.seekp(positionInFile);
|
||||
fout.write((char*)&usedEdgeCounter, sizeof(unsigned));
|
||||
fout.close();
|
||||
|
||||
@ -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());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(0 < parsed_way.duration) {
|
||||
//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);
|
||||
@ -108,7 +108,8 @@ void ExtractorCallbacks::wayFunction(ExtractionWay &parsed_way) {
|
||||
parsed_way.roundabout,
|
||||
parsed_way.ignoreInGrid,
|
||||
(0 < parsed_way.duration),
|
||||
parsed_way.isAccessRestricted
|
||||
parsed_way.isAccessRestricted,
|
||||
parsed_way.forward_mode
|
||||
)
|
||||
);
|
||||
externalMemory->usedNodeIDs.push_back(parsed_way.path[n]);
|
||||
@ -132,7 +133,8 @@ void ExtractorCallbacks::wayFunction(ExtractionWay &parsed_way) {
|
||||
parsed_way.ignoreInGrid,
|
||||
(0 < parsed_way.duration),
|
||||
parsed_way.isAccessRestricted,
|
||||
(ExtractionWay::oneway == parsed_way.direction)
|
||||
(ExtractionWay::oneway == parsed_way.direction),
|
||||
parsed_way.backward_mode
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@ -35,6 +35,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#include "../DataStructures/NodeCoords.h"
|
||||
#include "../DataStructures/Restriction.h"
|
||||
#include "../DataStructures/TimingUtil.h"
|
||||
#include "../DataStructures/TravelMode.h"
|
||||
#include "../typedefs.h"
|
||||
|
||||
typedef boost::unordered_map<std::string, NodeID > StringMap;
|
||||
@ -59,8 +60,10 @@ struct ExtractionWay {
|
||||
roundabout = false;
|
||||
isAccessRestricted = false;
|
||||
ignoreInGrid = false;
|
||||
forward_mode = 0;
|
||||
backward_mode = 0;
|
||||
}
|
||||
|
||||
|
||||
enum Directions {
|
||||
notSure = 0, oneway, bidirectional, opposite
|
||||
};
|
||||
@ -76,6 +79,8 @@ struct ExtractionWay {
|
||||
bool roundabout;
|
||||
bool isAccessRestricted;
|
||||
bool ignoreInGrid;
|
||||
TravelMode forward_mode;
|
||||
TravelMode backward_mode;
|
||||
std::vector< NodeID > path;
|
||||
HashTable<std::string, std::string> keyVals;
|
||||
};
|
||||
@ -89,13 +94,13 @@ struct ExtractorRelation {
|
||||
};
|
||||
|
||||
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, 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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
NodeID start;
|
||||
@ -109,7 +114,8 @@ struct InternalExtractorEdge {
|
||||
bool isDurationSet;
|
||||
bool isAccessRestricted;
|
||||
bool isContraFlow;
|
||||
|
||||
TravelMode mode;
|
||||
|
||||
_Coordinate startCoord;
|
||||
_Coordinate targetCoord;
|
||||
|
||||
|
||||
@ -319,7 +319,7 @@ inline void PBFParser::parseWay(_ThreadData * threadData) {
|
||||
#pragma omp parallel for schedule ( guided )
|
||||
for(int i = 0; i < number_of_ways; ++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) {
|
||||
|
||||
@ -78,6 +78,8 @@ ScriptingEnvironment::ScriptingEnvironment(const char * fileName) {
|
||||
.def_readwrite("ignore_in_grid", &ExtractionWay::ignoreInGrid)
|
||||
.def_readwrite("tags", &ExtractionWay::keyVals)
|
||||
.def_readwrite("direction", &ExtractionWay::direction)
|
||||
.def_readwrite("forward_mode", &ExtractionWay::forward_mode)
|
||||
.def_readwrite("backward_mode", &ExtractionWay::backward_mode)
|
||||
.enum_("constants")
|
||||
[
|
||||
luabind::value("notSure", 0),
|
||||
|
||||
@ -24,11 +24,12 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#include "../typedefs.h"
|
||||
|
||||
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;
|
||||
unsigned nameID;
|
||||
unsigned durationOfSegment;
|
||||
short turnInstruction;
|
||||
TravelMode mode;
|
||||
};
|
||||
|
||||
struct RawRouteData {
|
||||
|
||||
@ -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();
|
||||
std::stack<std::pair<NodeID, NodeID> > recursionStack;
|
||||
|
||||
@ -144,7 +144,7 @@ public:
|
||||
recursionStack.push(std::make_pair(edge.first, middle));
|
||||
} else {
|
||||
assert(!ed.shortcut);
|
||||
unpackedPath.push_back(_PathData(ed.id, _queryData.nodeHelpDesk->getNameIndexFromEdgeID(ed.id), _queryData.nodeHelpDesk->getTurnInstructionFromEdgeID(ed.id), ed.distance) );
|
||||
unpackedPath.push_back(_PathData(ed.id, _queryData.nodeHelpDesk->getNameIndexFromEdgeID(ed.id), _queryData.nodeHelpDesk->getTurnInstructionFromEdgeID(ed.id), ed.distance, _queryData.nodeHelpDesk->getModeFromEdgeID(ed.id)) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -158,9 +158,12 @@ public:
|
||||
edge = recursionStack.top();
|
||||
recursionStack.pop();
|
||||
|
||||
|
||||
typename QueryDataT::Graph::EdgeIterator smallestEdge = SPECIAL_EDGEID;
|
||||
int smallestWeight = INT_MAX;
|
||||
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;
|
||||
if(_queryData.graph->GetTarget(eit) == edge.second && weight < smallestWeight && _queryData.graph->GetEdgeData(eit).forward){
|
||||
smallestEdge = eit;
|
||||
|
||||
@ -69,7 +69,7 @@ public:
|
||||
|
||||
middle1 = UINT_MAX;
|
||||
middle2 = UINT_MAX;
|
||||
|
||||
|
||||
//insert new starting nodes into forward heap, adjusted by previous distances.
|
||||
if(searchFrom1stStartNode) {
|
||||
forward_heap1.Insert(phantomNodePair.startPhantom.edgeBasedNode, -phantomNodePair.startPhantom.weight1, phantomNodePair.startPhantom.edgeBasedNode);
|
||||
@ -165,7 +165,7 @@ public:
|
||||
if(*(packedPath1.end()-1) != *(temporaryPackedPath1.begin())) {
|
||||
packedPath1.swap(packedPath2);
|
||||
std::swap(distance1, distance2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
packedPath1.insert(packedPath1.end(), temporaryPackedPath1.begin(), temporaryPackedPath1.end());
|
||||
@ -185,9 +185,17 @@ public:
|
||||
if(distance1 > distance2){
|
||||
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);
|
||||
super::UnpackPath(packedPath1, rawRouteData.computedShortestPath);
|
||||
rawRouteData.lengthOfShortestPath = std::min(distance1, distance2);
|
||||
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
@ -21,6 +21,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
|
||||
#include "QueryObjectsStorage.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) {
|
||||
INFO("loading graph data");
|
||||
@ -55,7 +57,7 @@ QueryObjectsStorage::QueryObjectsStorage(std::string hsgrPath, std::string ramIn
|
||||
if(!nodesInStream) { ERR(nodesPath << " not found"); }
|
||||
std::ifstream edgesInStream(edgesPath.c_str(), std::ios::binary);
|
||||
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);
|
||||
|
||||
//deserialize street name list
|
||||
|
||||
@ -26,8 +26,6 @@ or see http://www.gnu.org/licenses/agpl.txt.
|
||||
#include<string>
|
||||
|
||||
#include "../../DataStructures/NodeInformationHelpDesk.h"
|
||||
#include "../../DataStructures/QueryEdge.h"
|
||||
#include "../../DataStructures/StaticGraph.h"
|
||||
|
||||
struct QueryObjectsStorage {
|
||||
typedef StaticGraph<QueryEdge::EdgeData> QueryGraph;
|
||||
|
||||
@ -102,7 +102,8 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeL
|
||||
NodeID nameID;
|
||||
int length;
|
||||
bool isRoundabout, ignoreInGrid, isAccessRestricted, isContraFlow;
|
||||
|
||||
TravelMode mode;
|
||||
|
||||
for (EdgeID i=0; i<m; ++i) {
|
||||
in.read((char*)&source, 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*)&isAccessRestricted, sizeof(bool));
|
||||
in.read((char*)&isContraFlow, sizeof(bool));
|
||||
in.read((char*)&mode, sizeof(TravelMode));
|
||||
|
||||
GUARANTEE(length > 0, "loaded null length edge" );
|
||||
GUARANTEE(weight > 0, "loaded null weight");
|
||||
@ -151,7 +153,7 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeL
|
||||
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);
|
||||
}
|
||||
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));
|
||||
edgeList.resize(numberOfEdges);
|
||||
in.read((char*) &(edgeList[0]), numberOfEdges*sizeof(EdgeT));
|
||||
|
||||
return numberOfNodes;
|
||||
}
|
||||
|
||||
|
||||
@ -255,6 +255,7 @@ int main (int argc, char *argv[]) {
|
||||
ERR("Failed at edges of node " << node << " of " << numberOfNodes);
|
||||
}
|
||||
//Serialize edges
|
||||
//INFO( "createHierachy write, i: " << usedEdgeCounter << ", mode: " << (long)currentEdge.data.mode );
|
||||
edgeOutFile.write((char*) ¤tEdge, sizeof(StaticGraph<EdgeData>::_StrEdge));
|
||||
++edge;
|
||||
++usedEdgeCounter;
|
||||
|
||||
@ -1,10 +1,14 @@
|
||||
@routing @bicycle @mode
|
||||
Feature: Bike - Mode flag
|
||||
|
||||
# bicycle modes:
|
||||
# 1 bike
|
||||
# 2 ferry
|
||||
# 3 push
|
||||
|
||||
Background:
|
||||
Given the profile "bicycle"
|
||||
|
||||
@todo
|
||||
Scenario: Bike - Mode when using a ferry
|
||||
Given the node map
|
||||
| a | b | |
|
||||
@ -17,15 +21,14 @@ Feature: Bike - Mode flag
|
||||
| cd | primary | | |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | turns | modes |
|
||||
| a | d | ab,bc,cd | head,right,left, destination | bike,ferry,bike |
|
||||
| d | a | cd,bc,ab | head,right,left, destination | bike,ferry,bike |
|
||||
| c | a | bc,ab | head,left,destination | ferry,bike |
|
||||
| d | b | cd,bc | head,right,destination | bike,ferry |
|
||||
| a | c | ab,bc | head,right,destination | bike,ferry |
|
||||
| b | d | bc,cd | head,left,destination | ferry,bike |
|
||||
| from | to | route | turns | modes |
|
||||
| a | d | ab,bc,cd | head,right,left,destination | 1,2,1 |
|
||||
| d | a | cd,bc,ab | head,right,left,destination | 1,2,1 |
|
||||
| c | a | bc,ab | head,left,destination | 2,1 |
|
||||
| d | b | cd,bc | head,right,destination | 1,2 |
|
||||
| a | c | ab,bc | head,right,destination | 1,2 |
|
||||
| b | d | bc,cd | head,left,destination | 2,1 |
|
||||
|
||||
@todo
|
||||
Scenario: Bike - Mode when pushing bike against oneways
|
||||
Given the node map
|
||||
| a | b | |
|
||||
@ -38,15 +41,14 @@ Feature: Bike - Mode flag
|
||||
| cd | primary | |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | turns | modes |
|
||||
| a | d | ab,bc,cd | head,right,left,destination | bike,push,bike |
|
||||
| d | a | cd,bc,ab | head,right,left,destination | bike,push,bike |
|
||||
| c | a | bc,ab | head,left,destination | push,bike |
|
||||
| d | b | cd,bc | head,right,destination | bike,push |
|
||||
| a | c | ab,bc | head,right,destination | bike,push |
|
||||
| b | d | bc,cd | head,left,destination | push,bike |
|
||||
| from | to | route | turns | modes |
|
||||
| a | d | ab,bc,cd | head,right,left,destination | 1,1,1 |
|
||||
| d | a | cd,bc,ab | head,right,left,destination | 1,3,1 |
|
||||
| c | a | bc,ab | head,left,destination | 3,1 |
|
||||
| d | b | cd,bc | head,right,destination | 1,3 |
|
||||
| a | c | ab,bc | head,right,destination | 1,1 |
|
||||
| b | d | bc,cd | head,left,destination | 1,1 |
|
||||
|
||||
@todo
|
||||
Scenario: Bike - Mode when pushing on pedestrain streets
|
||||
Given the node map
|
||||
| a | b | |
|
||||
@ -59,15 +61,14 @@ Feature: Bike - Mode flag
|
||||
| cd | primary |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | turns | modes |
|
||||
| a | d | ab,bc,cd | head,right,left,destination | bike,push,bike |
|
||||
| d | a | cd,bc,ab | head,right,left,destination | bike,push,bike |
|
||||
| c | a | bc,ab | head,left,destination | push,bike |
|
||||
| d | b | cd,bc | head,right,destination | bike,push |
|
||||
| a | c | ab,bc | head,right,destination | bike,push |
|
||||
| b | d | bc,cd | head,left,destination | push,bike |
|
||||
| from | to | route | turns | modes |
|
||||
| a | d | ab,bc,cd | head,right,left,destination | 1,3,1 |
|
||||
| d | a | cd,bc,ab | head,right,left,destination | 1,3,1 |
|
||||
| c | a | bc,ab | head,left,destination | 3,1 |
|
||||
| d | b | cd,bc | head,right,destination | 1,3 |
|
||||
| a | c | ab,bc | head,right,destination | 1,3 |
|
||||
| b | d | bc,cd | head,left,destination | 3,1 |
|
||||
|
||||
@todo
|
||||
Scenario: Bike - Mode when pushing on pedestrain areas
|
||||
Given the node map
|
||||
| a | b | | |
|
||||
@ -80,10 +81,10 @@ Feature: Bike - Mode flag
|
||||
| df | primary | |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | modes |
|
||||
| a | f | ab,bcd,df | bike,push,bike |
|
||||
| f | a | df,bcd,ab | bike,push,bike |
|
||||
| d | a | bcd,ab | push,bike |
|
||||
| f | b | df,bcd | bike,push |
|
||||
| a | d | ab,bcd | bike,push |
|
||||
| b | f | bcd,df | push,bike |
|
||||
| from | to | route | modes |
|
||||
| a | f | ab,bcd,df | 1,3,1 |
|
||||
| f | a | df,bcd,ab | 1,3,1 |
|
||||
| d | a | bcd,ab | 3,1 |
|
||||
| f | b | df,bcd | 1,3 |
|
||||
| a | d | ab,bcd | 1,3 |
|
||||
| b | f | bcd,df | 3,1 |
|
||||
|
||||
@ -98,11 +98,11 @@ Feature: Bike - Accessability of different way types
|
||||
| cd | primary | |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | turns |
|
||||
| a | d | ab,bc,cd | head,right,left,destination |
|
||||
| d | a | cd,bc,ab | head,enter_contraflow,leave_contraflow,destination |
|
||||
| c | a | bc,ab | head,leave_contraflow,destination |
|
||||
| d | b | cd,bc | head,enter_contraflow,destination |
|
||||
| from | to | route | turns |
|
||||
| a | d | ab,bc,cd | head,right,left,destination |
|
||||
| d | a | cd,bc,ab | head,right,left,destination |
|
||||
| c | a | bc,ab | head,left,destination |
|
||||
| d | b | cd,bc | head,right,destination |
|
||||
|
||||
@todo
|
||||
Scenario: Bike - Instructions when pushing bike on footway/pedestrian, etc.
|
||||
@ -117,8 +117,22 @@ Feature: Bike - Accessability of different way types
|
||||
| cd | primary |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | turns |
|
||||
| a | d | ab,bc,cd | head,right,left,destination |
|
||||
| d | a | cd,bc,ab | head,enter_contraflow,leave_contraflow,destination |
|
||||
| c | a | bc,ab | head,leave_contraflow,destination |
|
||||
| d | b | cd,bc | head,enter_contraflow,destination |
|
||||
| from | to | route | turns |
|
||||
| a | d | ab,bc,cd | head,right,left,destination |
|
||||
| d | a | cd,bc,ab | head,right,left,destination |
|
||||
| c | a | bc,ab | head,left,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 |
|
||||
|
||||
@ -1,26 +1,82 @@
|
||||
@routing @testbot @mode
|
||||
Feature: Testbot - Mode flag
|
||||
|
||||
# testbot modes:
|
||||
# 1 normal
|
||||
# 2 route
|
||||
# 3 river downstream
|
||||
# 4 river upstream
|
||||
|
||||
Background:
|
||||
Given the profile "testbot"
|
||||
|
||||
@todo
|
||||
Scenario: Bike - Mode
|
||||
Given the node map
|
||||
| a | b | |
|
||||
| | c | d |
|
||||
Scenario: Testbot - Mode for routes
|
||||
Given the node map
|
||||
| a | b | | | |
|
||||
| | c | d | e | f |
|
||||
|
||||
And the ways
|
||||
| nodes | highway | route | duration |
|
||||
| ab | primary | | |
|
||||
| bc | | ferry | 0:01 |
|
||||
| cd | primary | | |
|
||||
And the ways
|
||||
| nodes | highway | route | duration |
|
||||
| ab | primary | | |
|
||||
| bc | | ferry | 0:01 |
|
||||
| cd | primary | | |
|
||||
| de | primary | | |
|
||||
| ef | primary | | |
|
||||
|
||||
When I route I should get
|
||||
| from | to | route | turns | modes |
|
||||
| a | d | ab,bc,cd | head,right,left,destination | bot,ferry,bot |
|
||||
| d | a | cd,bc,ab | head,right left,destination | bot,ferry,bot |
|
||||
| c | a | bc,ab | head,left,destination | ferry,bot |
|
||||
| d | b | cd,bc | head,right,destination | bot,ferry |
|
||||
| a | c | ab,bc | head,right,destination | bot,ferry |
|
||||
| b | d | bc,cd | head,left,destination | ferry,bot |
|
||||
When I route I should get
|
||||
| from | to | route | turns | modes |
|
||||
| a | d | ab,bc,cd | head,right,left,destination | 1,2,1 |
|
||||
| d | a | cd,bc,ab | head,right,left,destination | 1,2,1 |
|
||||
| c | a | bc,ab | head,left,destination | 2,1 |
|
||||
| d | b | cd,bc | head,right,destination | 1,2 |
|
||||
| a | c | ab,bc | head,right,destination | 1,2 |
|
||||
| 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 |
|
||||
|
||||
@ -177,6 +177,8 @@ function way_function (way)
|
||||
local area = way.tags:Find("area")
|
||||
local foot = way.tags:Find("foot")
|
||||
local surface = way.tags:Find("surface")
|
||||
local foot_forward = way.tags:Find("foot:forward")
|
||||
local foot_backward = way.tags:Find("foot:backward")
|
||||
|
||||
-- name
|
||||
if "" ~= ref and "" ~= name then
|
||||
@ -189,7 +191,10 @@ function way_function (way)
|
||||
way.name = "{highway:"..highway.."}" -- if no name exists, use way type
|
||||
-- this encoding scheme is excepted to be a temporary solution
|
||||
end
|
||||
|
||||
|
||||
way.forward_mode = 1
|
||||
way.backward_mode = 1
|
||||
|
||||
-- speed
|
||||
if route_speeds[route] then
|
||||
-- ferries (doesn't cover routes tagged using relations)
|
||||
@ -200,6 +205,8 @@ function way_function (way)
|
||||
else
|
||||
way.speed = route_speeds[route]
|
||||
end
|
||||
way.forward_mode = 2
|
||||
way.backward_mode = 2
|
||||
elseif railway and platform_speeds[railway] then
|
||||
-- railway platforms (old tagging scheme)
|
||||
way.speed = platform_speeds[railway]
|
||||
@ -224,16 +231,30 @@ function way_function (way)
|
||||
else
|
||||
-- biking not allowed, maybe we can push our 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 pedestrian_speeds[highway] then
|
||||
-- pedestrian-only ways and areas
|
||||
way.speed = pedestrian_speeds[highway]
|
||||
way.forward_mode = 3
|
||||
way.backward_mode = 3
|
||||
elseif man_made and man_made_speeds[man_made] then
|
||||
-- man made structures
|
||||
way.speed = man_made_speeds[man_made]
|
||||
way.forward_mode = 3
|
||||
way.backward_mode = 3
|
||||
elseif foot == 'yes' then
|
||||
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
|
||||
@ -286,14 +307,15 @@ function way_function (way)
|
||||
if junction ~= "roundabout" then
|
||||
if way.direction == Way.oneway then
|
||||
way.backward_speed = walking_speed
|
||||
way.backward_mode = 3
|
||||
elseif way.direction == Way.opposite then
|
||||
way.backward_speed = walking_speed
|
||||
way.backward_mode = 3
|
||||
way.speed = way.speed
|
||||
end
|
||||
end
|
||||
end
|
||||
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
|
||||
end
|
||||
end
|
||||
@ -336,8 +358,6 @@ function way_function (way)
|
||||
way.backward_speed = maxspeed_backward
|
||||
end
|
||||
|
||||
|
||||
|
||||
way.type = 1
|
||||
return 1
|
||||
end
|
||||
|
||||
@ -6,6 +6,12 @@
|
||||
-- Secondary road: 18km/h = 18000m/3600s = 100m/20s
|
||||
-- Tertiary road: 12km/h = 12000m/3600s = 100m/30s
|
||||
|
||||
-- modes:
|
||||
-- 1: normal
|
||||
-- 2: route
|
||||
-- 3: river downstream
|
||||
-- 4: river upstream
|
||||
|
||||
speed_profile = {
|
||||
["primary"] = 36,
|
||||
["secondary"] = 18,
|
||||
@ -23,6 +29,14 @@ ignore_areas = true -- future feature
|
||||
traffic_signal_penalty = 7 -- seconds
|
||||
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)
|
||||
-- don't use ipairs(), since it stops at the first nil value
|
||||
for i=1, #limits do
|
||||
@ -56,10 +70,14 @@ function way_function (way)
|
||||
local maxspeed_forward = tonumber(way.tags:Find( "maxspeed:forward"))
|
||||
local maxspeed_backward = tonumber(way.tags:Find( "maxspeed:backward"))
|
||||
|
||||
way.forward_mode = 1
|
||||
way.backward_mode = 1
|
||||
way.name = name
|
||||
|
||||
if route ~= nil and durationIsValid(duration) then
|
||||
way.duration = math.max( 1, parseDuration(duration) )
|
||||
way.forward_mode = 2
|
||||
way.backward_mode = 2
|
||||
else
|
||||
local speed_forw = speed_profile[highway] or speed_profile['default']
|
||||
local speed_back = speed_forw
|
||||
@ -68,7 +86,9 @@ function way_function (way)
|
||||
local temp_speed = speed_forw;
|
||||
speed_forw = 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
|
||||
speed_forw = maxspeed_forward
|
||||
|
||||
Loading…
Reference in New Issue
Block a user