Merge pull request #1154 from Project-OSRM/feature/travel_mode

travel mode, closes #569, #603 and #606. Great job!
This commit is contained in:
Dennis Luxen 2014-08-21 15:12:02 +02:00
commit 2727091e47
40 changed files with 943 additions and 378 deletions

View File

@ -181,7 +181,9 @@ EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const NodeID nod
reverse_dist_prefix_sum[i], reverse_dist_prefix_sum[i],
m_geometry_compressor.GetPositionForID(e1), m_geometry_compressor.GetPositionForID(e1),
i, i,
belongs_to_tiny_cc); belongs_to_tiny_cc,
forward_data.travel_mode,
reverse_data.travel_mode);
current_edge_source_coordinate_id = current_edge_target_coordinate_id; current_edge_source_coordinate_id = current_edge_target_coordinate_id;
BOOST_ASSERT(m_edge_based_node_list.back().IsCompressed()); BOOST_ASSERT(m_edge_based_node_list.back().IsCompressed());
@ -231,7 +233,9 @@ EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const NodeID nod
0, 0,
SPECIAL_EDGEID, SPECIAL_EDGEID,
0, 0,
belongs_to_tiny_cc); belongs_to_tiny_cc,
forward_data.travel_mode,
reverse_data.travel_mode);
BOOST_ASSERT(!m_edge_based_node_list.back().IsCompressed()); BOOST_ASSERT(!m_edge_based_node_list.back().IsCompressed());
} }
} }
@ -500,7 +504,6 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedNodes()
} }
BOOST_ASSERT(u < v); BOOST_ASSERT(u < v);
BOOST_ASSERT(edge_data.type != SHRT_MAX);
// Note: edges that end on barrier nodes or on a turn restriction // Note: edges that end on barrier nodes or on a turn restriction
// may actually be in two distinct components. We choose the smallest // may actually be in two distinct components. We choose the smallest
@ -648,7 +651,8 @@ EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string &original_edg
(edge_is_compressed ? m_geometry_compressor.GetPositionForID(e1) : v), (edge_is_compressed ? m_geometry_compressor.GetPositionForID(e1) : v),
edge_data1.nameID, edge_data1.nameID,
turn_instruction, turn_instruction,
edge_is_compressed); edge_is_compressed,
edge_data2.travel_mode);
++original_edges_counter; ++original_edges_counter;
@ -718,15 +722,6 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(const NodeID node_u,
const EdgeData &data1 = m_node_based_graph->GetEdgeData(edge1); const EdgeData &data1 = m_node_based_graph->GetEdgeData(edge1);
const EdgeData &data2 = m_node_based_graph->GetEdgeData(edge2); const EdgeData &data2 = m_node_based_graph->GetEdgeData(edge2);
if (!data1.contraFlow && data2.contraFlow)
{
return TurnInstruction::EnterAgainstAllowedDirection;
}
if (data1.contraFlow && !data2.contraFlow)
{
return TurnInstruction::LeaveAgainstAllowedDirection;
}
// roundabouts need to be handled explicitely // roundabouts need to be handled explicitely
if (data1.roundabout && data2.roundabout) if (data1.roundabout && data2.roundabout)
{ {

View File

@ -1,6 +1,7 @@
#ifndef EDGE_BASED_NODE_H #ifndef EDGE_BASED_NODE_H
#define EDGE_BASED_NODE_H #define EDGE_BASED_NODE_H
#include "../DataStructures/TravelMode.h"
#include "../Util/SimpleLogger.h" #include "../Util/SimpleLogger.h"
#include "../typedefs.h" #include "../typedefs.h"
@ -25,7 +26,9 @@ struct EdgeBasedNode
reverse_offset(0), reverse_offset(0),
packed_geometry_id(SPECIAL_EDGEID), packed_geometry_id(SPECIAL_EDGEID),
fwd_segment_position( std::numeric_limits<unsigned short>::max() ), fwd_segment_position( std::numeric_limits<unsigned short>::max() ),
is_in_tiny_cc(false) is_in_tiny_cc(false),
forward_travel_mode(TRAVEL_MODE_INACCESSIBLE),
backward_travel_mode(TRAVEL_MODE_INACCESSIBLE)
{ } { }
explicit EdgeBasedNode( explicit EdgeBasedNode(
@ -40,7 +43,9 @@ struct EdgeBasedNode
int reverse_offset, int reverse_offset,
unsigned packed_geometry_id, unsigned packed_geometry_id,
unsigned short fwd_segment_position, unsigned short fwd_segment_position,
bool belongs_to_tiny_component bool belongs_to_tiny_component,
TravelMode forward_travel_mode,
TravelMode backward_travel_mode
) : ) :
forward_edge_based_node_id(forward_edge_based_node_id), forward_edge_based_node_id(forward_edge_based_node_id),
reverse_edge_based_node_id(reverse_edge_based_node_id), reverse_edge_based_node_id(reverse_edge_based_node_id),
@ -53,7 +58,9 @@ struct EdgeBasedNode
reverse_offset(reverse_offset), reverse_offset(reverse_offset),
packed_geometry_id(packed_geometry_id), packed_geometry_id(packed_geometry_id),
fwd_segment_position(fwd_segment_position), fwd_segment_position(fwd_segment_position),
is_in_tiny_cc(belongs_to_tiny_component) is_in_tiny_cc(belongs_to_tiny_component),
forward_travel_mode(forward_travel_mode),
backward_travel_mode(backward_travel_mode)
{ {
BOOST_ASSERT((forward_edge_based_node_id != SPECIAL_NODEID) || BOOST_ASSERT((forward_edge_based_node_id != SPECIAL_NODEID) ||
(reverse_edge_based_node_id != SPECIAL_NODEID)); (reverse_edge_based_node_id != SPECIAL_NODEID));
@ -85,6 +92,8 @@ struct EdgeBasedNode
unsigned packed_geometry_id; // if set, then the edge represents a packed geometry unsigned packed_geometry_id; // if set, then the edge represents a packed geometry
unsigned short fwd_segment_position; // segment id in a compressed geometry unsigned short fwd_segment_position; // segment id in a compressed geometry
bool is_in_tiny_cc; bool is_in_tiny_cc;
TravelMode forward_travel_mode : 4;
TravelMode backward_travel_mode : 4;
}; };
#endif //EDGE_BASED_NODE_H #endif //EDGE_BASED_NODE_H

View File

@ -52,17 +52,15 @@ NodeBasedEdge::NodeBasedEdge(NodeID source,
EdgeWeight weight, EdgeWeight weight,
bool forward, bool forward,
bool backward, bool backward,
short type,
bool roundabout, bool roundabout,
bool in_tiny_cc, bool in_tiny_cc,
bool access_restricted, bool access_restricted,
bool contra_flow, TravelMode travel_mode,
bool is_split) bool is_split)
: source(source), target(target), name_id(name_id), weight(weight), type(type), : source(source), target(target), name_id(name_id), weight(weight),
forward(forward), backward(backward), roundabout(roundabout), in_tiny_cc(in_tiny_cc), forward(forward), backward(backward), roundabout(roundabout), in_tiny_cc(in_tiny_cc),
access_restricted(access_restricted), contra_flow(contra_flow), is_split(is_split) access_restricted(access_restricted), is_split(is_split), travel_mode(travel_mode)
{ {
BOOST_ASSERT_MSG(type > 0, "negative edge type");
} }
bool EdgeBasedEdge::operator<(const EdgeBasedEdge &other) const bool EdgeBasedEdge::operator<(const EdgeBasedEdge &other) const

View File

@ -28,6 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef IMPORT_EDGE_H #ifndef IMPORT_EDGE_H
#define IMPORT_EDGE_H #define IMPORT_EDGE_H
#include "../DataStructures/TravelMode.h"
#include "../typedefs.h" #include "../typedefs.h"
struct NodeBasedEdge struct NodeBasedEdge
@ -40,25 +41,23 @@ struct NodeBasedEdge
EdgeWeight weight, EdgeWeight weight,
bool forward, bool forward,
bool backward, bool backward,
short type,
bool roundabout, bool roundabout,
bool in_tiny_cc, bool in_tiny_cc,
bool access_restricted, bool access_restricted,
bool contra_flow, TravelMode travel_mode,
bool is_split); bool is_split);
NodeID source; NodeID source;
NodeID target; NodeID target;
NodeID name_id; NodeID name_id;
EdgeWeight weight; EdgeWeight weight;
short type;
bool forward : 1; bool forward : 1;
bool backward : 1; bool backward : 1;
bool roundabout : 1; bool roundabout : 1;
bool in_tiny_cc : 1; bool in_tiny_cc : 1;
bool access_restricted : 1; bool access_restricted : 1;
bool contra_flow : 1;
bool is_split : 1; bool is_split : 1;
TravelMode travel_mode : 4;
NodeBasedEdge() = delete; NodeBasedEdge() = delete;
}; };

View File

@ -13,23 +13,22 @@ struct NodeBasedEdgeData
{ {
NodeBasedEdgeData() NodeBasedEdgeData()
: distance(INVALID_EDGE_WEIGHT), edgeBasedNodeID(SPECIAL_NODEID), : distance(INVALID_EDGE_WEIGHT), edgeBasedNodeID(SPECIAL_NODEID),
nameID(std::numeric_limits<unsigned>::max()), type(std::numeric_limits<short>::max()), nameID(std::numeric_limits<unsigned>::max()),
isAccessRestricted(false), shortcut(false), forward(false), backward(false), isAccessRestricted(false), shortcut(false), forward(false), backward(false),
roundabout(false), ignore_in_grid(false), contraFlow(false) roundabout(false), ignore_in_grid(false), travel_mode(TRAVEL_MODE_INACCESSIBLE)
{ {
} }
int distance; int distance;
unsigned edgeBasedNodeID; unsigned edgeBasedNodeID;
unsigned nameID; unsigned nameID;
short type;
bool isAccessRestricted : 1; bool isAccessRestricted : 1;
bool shortcut : 1; bool shortcut : 1;
bool forward : 1; bool forward : 1;
bool backward : 1; bool backward : 1;
bool roundabout : 1; bool roundabout : 1;
bool ignore_in_grid : 1; bool ignore_in_grid : 1;
bool contraFlow : 1; TravelMode travel_mode : 4;
void SwapDirectionFlags() void SwapDirectionFlags()
{ {
@ -42,7 +41,7 @@ struct NodeBasedEdgeData
{ {
return (forward == other.forward) && (backward == other.backward) && return (forward == other.forward) && (backward == other.backward) &&
(nameID == other.nameID) && (ignore_in_grid == other.ignore_in_grid) && (nameID == other.nameID) && (ignore_in_grid == other.ignore_in_grid) &&
(contraFlow == other.contraFlow); (travel_mode == other.travel_mode);
} }
}; };
@ -91,9 +90,9 @@ NodeBasedDynamicGraphFromImportEdges(int number_of_nodes, std::vector<ImportEdge
edge.data.roundabout = import_edge.roundabout; edge.data.roundabout = import_edge.roundabout;
edge.data.ignore_in_grid = import_edge.in_tiny_cc; edge.data.ignore_in_grid = import_edge.in_tiny_cc;
edge.data.nameID = import_edge.name_id; edge.data.nameID = import_edge.name_id;
edge.data.type = import_edge.type;
edge.data.isAccessRestricted = import_edge.access_restricted; edge.data.isAccessRestricted = import_edge.access_restricted;
edge.data.contraFlow = import_edge.contra_flow; edge.data.travel_mode = import_edge.travel_mode;
edges_list.push_back(edge); edges_list.push_back(edge);
if (!import_edge.is_split) if (!import_edge.is_split)

View File

@ -29,6 +29,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define ORIGINAL_EDGE_DATA_H #define ORIGINAL_EDGE_DATA_H
#include "TurnInstructions.h" #include "TurnInstructions.h"
#include "../DataStructures/TravelMode.h"
#include "../typedefs.h" #include "../typedefs.h"
#include <limits> #include <limits>
@ -38,16 +39,18 @@ struct OriginalEdgeData
explicit OriginalEdgeData(NodeID via_node, explicit OriginalEdgeData(NodeID via_node,
unsigned name_id, unsigned name_id,
TurnInstruction turn_instruction, TurnInstruction turn_instruction,
bool compressed_geometry) bool compressed_geometry,
TravelMode travel_mode)
: via_node(via_node), name_id(name_id), turn_instruction(turn_instruction), : via_node(via_node), name_id(name_id), turn_instruction(turn_instruction),
compressed_geometry(compressed_geometry) compressed_geometry(compressed_geometry), travel_mode(travel_mode)
{ {
} }
OriginalEdgeData() OriginalEdgeData()
: via_node(std::numeric_limits<unsigned>::max()), : via_node(std::numeric_limits<unsigned>::max()),
name_id(std::numeric_limits<unsigned>::max()), name_id(std::numeric_limits<unsigned>::max()),
turn_instruction(TurnInstruction::NoTurn), compressed_geometry(false) turn_instruction(TurnInstruction::NoTurn), compressed_geometry(false),
travel_mode(TRAVEL_MODE_INACCESSIBLE)
{ {
} }
@ -55,6 +58,7 @@ struct OriginalEdgeData
unsigned name_id; unsigned name_id;
TurnInstruction turn_instruction; TurnInstruction turn_instruction;
bool compressed_geometry; bool compressed_geometry;
TravelMode travel_mode;
}; };
#endif // ORIGINAL_EDGE_DATA_H #endif // ORIGINAL_EDGE_DATA_H

View File

@ -29,6 +29,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define PHANTOM_NODES_H #define PHANTOM_NODES_H
#include <osrm/Coordinate.h> #include <osrm/Coordinate.h>
#include "../DataStructures/TravelMode.h"
#include "../Util/SimpleLogger.h" #include "../Util/SimpleLogger.h"
#include "../typedefs.h" #include "../typedefs.h"
@ -39,7 +40,8 @@ struct PhantomNode
PhantomNode(NodeID forward_node_id, NodeID reverse_node_id, unsigned name_id, PhantomNode(NodeID forward_node_id, NodeID reverse_node_id, unsigned name_id,
int forward_weight, int reverse_weight, int forward_offset, int reverse_offset, int forward_weight, int reverse_weight, int forward_offset, int reverse_offset,
unsigned packed_geometry_id, FixedPointCoordinate &location, unsigned packed_geometry_id, FixedPointCoordinate &location,
unsigned short fwd_segment_position) : unsigned short fwd_segment_position,
TravelMode forward_travel_mode, TravelMode backward_travel_mode) :
forward_node_id(forward_node_id), forward_node_id(forward_node_id),
reverse_node_id(reverse_node_id), reverse_node_id(reverse_node_id),
name_id(name_id), name_id(name_id),
@ -49,7 +51,9 @@ struct PhantomNode
reverse_offset(reverse_offset), reverse_offset(reverse_offset),
packed_geometry_id(packed_geometry_id), packed_geometry_id(packed_geometry_id),
location(location), location(location),
fwd_segment_position(fwd_segment_position) fwd_segment_position(fwd_segment_position),
forward_travel_mode(forward_travel_mode),
backward_travel_mode(backward_travel_mode)
{ } { }
PhantomNode() : PhantomNode() :
@ -61,7 +65,9 @@ struct PhantomNode
forward_offset(0), forward_offset(0),
reverse_offset(0), reverse_offset(0),
packed_geometry_id(SPECIAL_EDGEID), packed_geometry_id(SPECIAL_EDGEID),
fwd_segment_position(0) fwd_segment_position(0),
forward_travel_mode(TRAVEL_MODE_INACCESSIBLE),
backward_travel_mode(TRAVEL_MODE_INACCESSIBLE)
{ } { }
NodeID forward_node_id; NodeID forward_node_id;
@ -74,7 +80,9 @@ struct PhantomNode
unsigned packed_geometry_id; unsigned packed_geometry_id;
FixedPointCoordinate location; FixedPointCoordinate location;
unsigned short fwd_segment_position; unsigned short fwd_segment_position;
TravelMode forward_travel_mode : 4;
TravelMode backward_travel_mode : 4;
int GetForwardWeightPlusOffset() const int GetForwardWeightPlusOffset() const
{ {
if (SPECIAL_NODEID == forward_node_id) if (SPECIAL_NODEID == forward_node_id)

View File

@ -29,6 +29,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define RAW_ROUTE_DATA_H #define RAW_ROUTE_DATA_H
#include "../DataStructures/PhantomNodes.h" #include "../DataStructures/PhantomNodes.h"
#include "../DataStructures/TravelMode.h"
#include "../DataStructures/TurnInstructions.h" #include "../DataStructures/TurnInstructions.h"
#include "../typedefs.h" #include "../typedefs.h"
@ -41,18 +42,25 @@ struct PathData
PathData() PathData()
: node(SPECIAL_NODEID), name_id(INVALID_EDGE_WEIGHT), : node(SPECIAL_NODEID), name_id(INVALID_EDGE_WEIGHT),
segment_duration(INVALID_EDGE_WEIGHT), segment_duration(INVALID_EDGE_WEIGHT),
turn_instruction(TurnInstruction::NoTurn) turn_instruction(TurnInstruction::NoTurn),
travel_mode(TRAVEL_MODE_INACCESSIBLE)
{ {
} }
PathData(NodeID node, unsigned name_id, TurnInstruction turn_instruction, EdgeWeight segment_duration) PathData(NodeID node,
: node(node), name_id(name_id), segment_duration(segment_duration), turn_instruction(turn_instruction) unsigned name_id,
TurnInstruction turn_instruction,
EdgeWeight segment_duration,
TravelMode travel_mode)
: node(node), name_id(name_id), segment_duration(segment_duration), turn_instruction(turn_instruction),
travel_mode(travel_mode)
{ {
} }
NodeID node; NodeID node;
unsigned name_id; unsigned name_id;
EdgeWeight segment_duration; EdgeWeight segment_duration;
TurnInstruction turn_instruction; TurnInstruction turn_instruction;
TravelMode travel_mode : 4;
}; };
struct RawRouteData struct RawRouteData

View File

@ -30,6 +30,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "TurnInstructions.h" #include "TurnInstructions.h"
#include "../DataStructures/TravelMode.h"
#include "../typedefs.h" #include "../typedefs.h"
#include <osrm/Coordinate.h> #include <osrm/Coordinate.h>
@ -43,8 +44,9 @@ struct SegmentInformation
float length; float length;
short bearing; // more than enough [0..3600] fits into 12 bits short bearing; // more than enough [0..3600] fits into 12 bits
TurnInstruction turn_instruction; TurnInstruction turn_instruction;
bool necessary:1; TravelMode travel_mode;
bool is_via_location:1; bool necessary;
bool is_via_location;
explicit SegmentInformation(const FixedPointCoordinate &location, explicit SegmentInformation(const FixedPointCoordinate &location,
const NodeID name_id, const NodeID name_id,
@ -52,9 +54,11 @@ struct SegmentInformation
const float length, const float length,
const TurnInstruction turn_instruction, const TurnInstruction turn_instruction,
const bool necessary, const bool necessary,
const bool is_via_location) const bool is_via_location,
const TravelMode travel_mode)
: location(location), name_id(name_id), duration(duration), length(length), bearing(0), : location(location), name_id(name_id), duration(duration), length(length), bearing(0),
turn_instruction(turn_instruction), necessary(necessary), is_via_location(is_via_location) turn_instruction(turn_instruction), travel_mode(travel_mode), necessary(necessary),
is_via_location(is_via_location)
{ {
} }
@ -62,9 +66,11 @@ struct SegmentInformation
const NodeID name_id, const NodeID name_id,
const EdgeWeight duration, const EdgeWeight duration,
const float length, const float length,
const TurnInstruction turn_instruction) const TurnInstruction turn_instruction,
const TravelMode travel_mode)
: location(location), name_id(name_id), duration(duration), length(length), bearing(0), : location(location), name_id(name_id), duration(duration), length(length), bearing(0),
turn_instruction(turn_instruction), necessary(turn_instruction != TurnInstruction::NoTurn), is_via_location(false) turn_instruction(turn_instruction), travel_mode(travel_mode),
necessary(turn_instruction != TurnInstruction::NoTurn), is_via_location(false)
{ {
} }
}; };

View File

@ -801,7 +801,9 @@ class StaticRTree
current_segment.reverse_offset, current_segment.reverse_offset,
current_segment.packed_geometry_id, current_segment.packed_geometry_id,
foot_point_coordinate_on_segment, foot_point_coordinate_on_segment,
current_segment.fwd_segment_position); current_segment.fwd_segment_position,
current_segment.forward_travel_mode,
current_segment.backward_travel_mode);
// Hack to fix rounding errors and wandering via nodes. // Hack to fix rounding errors and wandering via nodes.
FixUpRoundingIssue(input_coordinate, result_phantom_node_vector.back()); FixUpRoundingIssue(input_coordinate, result_phantom_node_vector.back());
@ -1077,7 +1079,9 @@ class StaticRTree
current_edge.reverse_offset, current_edge.reverse_offset,
current_edge.packed_geometry_id, current_edge.packed_geometry_id,
nearest, nearest,
current_edge.fwd_segment_position}; current_edge.fwd_segment_position,
current_edge.forward_travel_mode,
current_edge.backward_travel_mode};
nearest_edge = current_edge; nearest_edge = current_edge;
} }
} }

View File

@ -0,0 +1,35 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TRAVEL_MODE_H
#define TRAVEL_MODE_H
using TravelMode = unsigned char;
static const TravelMode TRAVEL_MODE_INACCESSIBLE = 0;
static const TravelMode TRAVEL_MODE_DEFAULT = 1;
#endif /* TRAVEL_MODE_H */

View File

@ -45,8 +45,11 @@ void DescriptionFactory::SetStartSegment(const PhantomNode &source, const bool t
start_phantom = source; start_phantom = source;
const EdgeWeight segment_duration = const EdgeWeight segment_duration =
(traversed_in_reverse ? source.reverse_weight : source.forward_weight); (traversed_in_reverse ? source.reverse_weight : source.forward_weight);
AppendSegment(source.location, const TravelMode travel_mode =
PathData(0, source.name_id, TurnInstruction::HeadOn, segment_duration)); (traversed_in_reverse ? source.backward_travel_mode : source.forward_travel_mode);
AppendSegment(
source.location,
PathData(0, source.name_id, TurnInstruction::HeadOn, segment_duration, travel_mode));
BOOST_ASSERT(path_description.back().duration == segment_duration); BOOST_ASSERT(path_description.back().duration == segment_duration);
} }
@ -57,6 +60,8 @@ void DescriptionFactory::SetEndSegment(const PhantomNode &target,
target_phantom = target; target_phantom = target;
const EdgeWeight segment_duration = const EdgeWeight segment_duration =
(traversed_in_reverse ? target.reverse_weight : target.forward_weight); (traversed_in_reverse ? target.reverse_weight : target.forward_weight);
const TravelMode travel_mode =
(traversed_in_reverse ? target.backward_travel_mode : target.forward_travel_mode);
path_description.emplace_back(target.location, path_description.emplace_back(target.location,
target.name_id, target.name_id,
segment_duration, segment_duration,
@ -64,24 +69,44 @@ void DescriptionFactory::SetEndSegment(const PhantomNode &target,
is_via_location ? TurnInstruction::ReachViaLocation is_via_location ? TurnInstruction::ReachViaLocation
: TurnInstruction::NoTurn, : TurnInstruction::NoTurn,
true, true,
true); true,
travel_mode);
BOOST_ASSERT(path_description.back().duration == segment_duration); BOOST_ASSERT(path_description.back().duration == segment_duration);
} }
void DescriptionFactory::AppendSegment(const FixedPointCoordinate &coordinate, void DescriptionFactory::AppendSegment(const FixedPointCoordinate &coordinate,
const PathData &path_point) const PathData &path_point)
{ {
if ((1 == path_description.size()) && (path_description.back().location == coordinate)) // if the start location is on top of a node, the first movement might be zero-length,
// in which case we dont' add a new description, but instead update the existing one
if ((1 == path_description.size()) && (path_description.front().location == coordinate))
{ {
path_description.back().name_id = path_point.name_id; if (path_point.segment_duration > 0)
{
path_description.front().name_id = path_point.name_id;
path_description.front().travel_mode = path_point.travel_mode;
}
return; return;
} }
// make sure mode changes are announced, even when there otherwise is no turn
const TurnInstruction turn = [&]() -> TurnInstruction
{
if (TurnInstruction::NoTurn == path_point.turn_instruction &&
path_description.front().travel_mode != path_point.travel_mode &&
path_point.segment_duration > 0)
{
return TurnInstruction::GoStraight;
}
return path_point.turn_instruction;
}();
path_description.emplace_back(coordinate, path_description.emplace_back(coordinate,
path_point.name_id, path_point.name_id,
path_point.segment_duration, path_point.segment_duration,
0.f, 0.f,
path_point.turn_instruction); turn,
path_point.travel_mode);
} }
JSON::Value DescriptionFactory::AppendEncodedPolylineString(const bool return_encoded) JSON::Value DescriptionFactory::AppendEncodedPolylineString(const bool return_encoded)

View File

@ -356,6 +356,7 @@ template <class DataFacadeT> class JSONDescriptor : public BaseDescriptor<DataFa
json_instruction_row.values.push_back(Azimuth::Get(bearing_value)); json_instruction_row.values.push_back(Azimuth::Get(bearing_value));
json_instruction_row.values.push_back( json_instruction_row.values.push_back(
static_cast<unsigned>(round(bearing_value))); static_cast<unsigned>(round(bearing_value)));
json_instruction_row.values.push_back(segment.travel_mode);
route_segments_list.emplace_back( route_segments_list.emplace_back(
segment.name_id, segment.name_id,

View File

@ -330,7 +330,6 @@ void ExtractionContainers::PrepareData(const std::string &output_file_name,
edge_iterator->source_coordinate.lon != std::numeric_limits<int>::min()) edge_iterator->source_coordinate.lon != std::numeric_limits<int>::min())
{ {
BOOST_ASSERT(edge_iterator->speed != -1); BOOST_ASSERT(edge_iterator->speed != -1);
BOOST_ASSERT(edge_iterator->type >= 0);
edge_iterator->target_coordinate.lat = node_iterator->lat; edge_iterator->target_coordinate.lat = node_iterator->lat;
edge_iterator->target_coordinate.lon = node_iterator->lon; edge_iterator->target_coordinate.lon = node_iterator->lon;
@ -371,12 +370,15 @@ void ExtractionContainers::PrepareData(const std::string &output_file_name,
} }
file_out_stream.write((char *)&integer_weight, sizeof(int)); file_out_stream.write((char *)&integer_weight, sizeof(int));
file_out_stream.write((char *)&edge_iterator->type, sizeof(short));
file_out_stream.write((char *)&edge_iterator->name_id, sizeof(unsigned)); file_out_stream.write((char *)&edge_iterator->name_id, sizeof(unsigned));
file_out_stream.write((char *)&edge_iterator->is_roundabout, sizeof(bool)); file_out_stream.write((char *)&edge_iterator->is_roundabout, sizeof(bool));
file_out_stream.write((char *)&edge_iterator->is_in_tiny_cc, sizeof(bool)); file_out_stream.write((char *)&edge_iterator->is_in_tiny_cc, sizeof(bool));
file_out_stream.write((char *)&edge_iterator->is_access_restricted, sizeof(bool)); file_out_stream.write((char *)&edge_iterator->is_access_restricted, sizeof(bool));
file_out_stream.write((char *)&edge_iterator->is_contra_flow, sizeof(bool));
// cannot take adress of bit field, so use local
const TravelMode travel_mode = edge_iterator->travel_mode;
file_out_stream.write((char *)&travel_mode, sizeof(TravelMode));
file_out_stream.write((char *)&edge_iterator->is_split, sizeof(bool)); file_out_stream.write((char *)&edge_iterator->is_split, sizeof(bool));
++number_of_used_edges; ++number_of_used_edges;
} }

View File

@ -29,6 +29,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define EXTRACTION_WAY_H #define EXTRACTION_WAY_H
#include "../DataStructures/HashTable.h" #include "../DataStructures/HashTable.h"
#include "../DataStructures/TravelMode.h"
#include "../typedefs.h" #include "../typedefs.h"
#include <string> #include <string>
@ -44,15 +45,15 @@ struct ExtractionWay
nameID = INVALID_NAMEID; nameID = INVALID_NAMEID;
path.clear(); path.clear();
keyVals.Clear(); keyVals.Clear();
direction = ExtractionWay::notSure; forward_speed = -1;
speed = -1;
backward_speed = -1; backward_speed = -1;
duration = -1; duration = -1;
type = -1;
access = true; access = true;
roundabout = false; roundabout = false;
isAccessRestricted = false; isAccessRestricted = false;
ignoreInGrid = false; ignoreInGrid = false;
forward_travel_mode = TRAVEL_MODE_DEFAULT;
backward_travel_mode = TRAVEL_MODE_DEFAULT;
} }
enum Directions enum Directions
@ -60,20 +61,70 @@ struct ExtractionWay
oneway, oneway,
bidirectional, bidirectional,
opposite }; opposite };
// These accessor methods exists to support the depreciated "way.direction" access
// in LUA. Since the direction attribute was removed from ExtractionWay, the
// accessors translate to/from the mode attributes.
inline void set_direction(const Directions m)
{
if (Directions::oneway == m)
{
forward_travel_mode = TRAVEL_MODE_DEFAULT;
backward_travel_mode = TRAVEL_MODE_INACCESSIBLE;
}
else if (Directions::opposite == m)
{
forward_travel_mode = TRAVEL_MODE_INACCESSIBLE;
backward_travel_mode = TRAVEL_MODE_DEFAULT;
}
else if (Directions::bidirectional == m)
{
forward_travel_mode = TRAVEL_MODE_DEFAULT;
backward_travel_mode = TRAVEL_MODE_DEFAULT;
}
}
inline const Directions get_direction() const
{
if (TRAVEL_MODE_INACCESSIBLE != forward_travel_mode && TRAVEL_MODE_INACCESSIBLE != backward_travel_mode)
{
return Directions::bidirectional;
}
else if (TRAVEL_MODE_INACCESSIBLE != forward_travel_mode)
{
return Directions::oneway;
}
else if (TRAVEL_MODE_INACCESSIBLE != backward_travel_mode)
{
return Directions::opposite;
}
else
{
return Directions::notSure;
}
}
// These accessors exists because it's not possible to take the address of a bitfield,
// and LUA therefore cannot read/write the mode attributes directly.
inline void set_forward_mode(const TravelMode m) { forward_travel_mode = m; }
inline const TravelMode get_forward_mode() const { return forward_travel_mode; }
inline void set_backward_mode(const TravelMode m) { backward_travel_mode = m; }
inline const TravelMode get_backward_mode() const { return backward_travel_mode; }
unsigned id; unsigned id;
unsigned nameID; unsigned nameID;
double speed; double forward_speed;
double backward_speed; double backward_speed;
double duration; double duration;
Directions direction;
std::string name; std::string name;
short type;
bool access; bool access;
bool roundabout; bool roundabout;
bool isAccessRestricted; bool isAccessRestricted;
bool ignoreInGrid; bool ignoreInGrid;
std::vector<NodeID> path; std::vector<NodeID> path;
HashTable<std::string, std::string> keyVals; HashTable<std::string, std::string> keyVals;
TravelMode forward_travel_mode : 4;
TravelMode backward_travel_mode : 4;
}; };
#endif // EXTRACTION_WAY_H #endif // EXTRACTION_WAY_H

View File

@ -63,7 +63,11 @@ bool ExtractorCallbacks::ProcessRestriction(const InputRestrictionContainer &res
/** warning: caller needs to take care of synchronization! */ /** warning: caller needs to take care of synchronization! */
void ExtractorCallbacks::ProcessWay(ExtractionWay &parsed_way) void ExtractorCallbacks::ProcessWay(ExtractionWay &parsed_way)
{ {
if ((0 >= parsed_way.speed) && (0 >= parsed_way.duration)) if (((0 >= parsed_way.forward_speed) ||
(TRAVEL_MODE_INACCESSIBLE == parsed_way.forward_travel_mode)) &&
((0 >= parsed_way.backward_speed) ||
(TRAVEL_MODE_INACCESSIBLE == parsed_way.backward_travel_mode)) &&
(0 >= parsed_way.duration))
{ // Only true if the way is specified by the speed profile { // Only true if the way is specified by the speed profile
return; return;
} }
@ -84,10 +88,10 @@ void ExtractorCallbacks::ProcessWay(ExtractionWay &parsed_way)
{ {
// TODO: iterate all way segments and set duration corresponding to the length of each // TODO: iterate all way segments and set duration corresponding to the length of each
// segment // segment
parsed_way.speed = parsed_way.duration / (parsed_way.path.size() - 1); parsed_way.forward_speed = parsed_way.duration / (parsed_way.path.size() - 1);
} }
if (std::numeric_limits<double>::epsilon() >= std::abs(-1. - parsed_way.speed)) if (std::numeric_limits<double>::epsilon() >= std::abs(-1. - parsed_way.forward_speed))
{ {
SimpleLogger().Write(logDEBUG) << "found way with bogus speed, id: " << parsed_way.id; SimpleLogger().Write(logDEBUG) << "found way with bogus speed, id: " << parsed_way.id;
return; return;
@ -106,29 +110,34 @@ void ExtractorCallbacks::ProcessWay(ExtractionWay &parsed_way)
parsed_way.nameID = string_map_iterator->second; parsed_way.nameID = string_map_iterator->second;
} }
if (ExtractionWay::opposite == parsed_way.direction) if (TRAVEL_MODE_INACCESSIBLE == parsed_way.forward_travel_mode)
{ {
std::reverse(parsed_way.path.begin(), parsed_way.path.end()); std::reverse(parsed_way.path.begin(), parsed_way.path.end());
parsed_way.direction = ExtractionWay::oneway; parsed_way.forward_travel_mode = parsed_way.backward_travel_mode;
parsed_way.backward_travel_mode = TRAVEL_MODE_INACCESSIBLE;
} }
const bool split_edge = const bool split_edge =
(parsed_way.backward_speed > 0) && (parsed_way.speed != parsed_way.backward_speed); (parsed_way.forward_speed>0) && (TRAVEL_MODE_INACCESSIBLE != parsed_way.forward_travel_mode) &&
(parsed_way.backward_speed>0) && (TRAVEL_MODE_INACCESSIBLE != parsed_way.backward_travel_mode) &&
((parsed_way.forward_speed != parsed_way.backward_speed) ||
(parsed_way.forward_travel_mode != parsed_way.backward_travel_mode));
BOOST_ASSERT(parsed_way.forward_travel_mode>0);
for (unsigned n = 0; n < (parsed_way.path.size() - 1); ++n) for (unsigned n = 0; n < (parsed_way.path.size() - 1); ++n)
{ {
external_memory.all_edges_list.push_back(InternalExtractorEdge( external_memory.all_edges_list.push_back(InternalExtractorEdge(
parsed_way.path[n], parsed_way.path[n],
parsed_way.path[n + 1], parsed_way.path[n + 1],
parsed_way.type, ((split_edge || TRAVEL_MODE_INACCESSIBLE == parsed_way.backward_travel_mode) ? ExtractionWay::oneway
(split_edge ? ExtractionWay::oneway : parsed_way.direction), : ExtractionWay::bidirectional),
parsed_way.speed, parsed_way.forward_speed,
parsed_way.nameID, parsed_way.nameID,
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,
false, parsed_way.forward_travel_mode,
split_edge)); split_edge));
external_memory.used_node_id_list.push_back(parsed_way.path[n]); external_memory.used_node_id_list.push_back(parsed_way.path[n]);
} }
@ -144,13 +153,13 @@ void ExtractorCallbacks::ProcessWay(ExtractionWay &parsed_way)
if (split_edge) if (split_edge)
{ // Only true if the way should be split { // Only true if the way should be split
BOOST_ASSERT(parsed_way.backward_travel_mode>0);
std::reverse(parsed_way.path.begin(), parsed_way.path.end()); std::reverse(parsed_way.path.begin(), parsed_way.path.end());
for (std::vector<NodeID>::size_type n = 0; n < parsed_way.path.size() - 1; ++n) for (std::vector<NodeID>::size_type n = 0; n < parsed_way.path.size() - 1; ++n)
{ {
external_memory.all_edges_list.push_back( external_memory.all_edges_list.push_back(
InternalExtractorEdge(parsed_way.path[n], InternalExtractorEdge(parsed_way.path[n],
parsed_way.path[n + 1], parsed_way.path[n + 1],
parsed_way.type,
ExtractionWay::oneway, ExtractionWay::oneway,
parsed_way.backward_speed, parsed_way.backward_speed,
parsed_way.nameID, parsed_way.nameID,
@ -158,7 +167,7 @@ void ExtractorCallbacks::ProcessWay(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), parsed_way.backward_travel_mode,
split_edge)); split_edge));
} }
external_memory.way_start_end_id_list.push_back( external_memory.way_start_end_id_list.push_back(

View File

@ -29,6 +29,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define INTERNAL_EXTRACTOR_EDGE_H #define INTERNAL_EXTRACTOR_EDGE_H
#include "../typedefs.h" #include "../typedefs.h"
#include "../DataStructures/TravelMode.h"
#include <osrm/Coordinate.h> #include <osrm/Coordinate.h>
#include <boost/assert.hpp> #include <boost/assert.hpp>
@ -36,15 +37,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
struct InternalExtractorEdge struct InternalExtractorEdge
{ {
InternalExtractorEdge() InternalExtractorEdge()
: start(0), target(0), type(0), direction(0), speed(0), name_id(0), is_roundabout(false), : start(0), target(0), direction(0), speed(0), name_id(0), is_roundabout(false),
is_in_tiny_cc(false), is_duration_set(false), is_access_restricted(false), is_in_tiny_cc(false), is_duration_set(false), is_access_restricted(false),
is_contra_flow(false), is_split(false) travel_mode(TRAVEL_MODE_INACCESSIBLE), is_split(false)
{ {
} }
explicit InternalExtractorEdge(NodeID start, explicit InternalExtractorEdge(NodeID start,
NodeID target, NodeID target,
short type,
short direction, short direction,
double speed, double speed,
unsigned name_id, unsigned name_id,
@ -52,30 +52,28 @@ struct InternalExtractorEdge
bool is_in_tiny_cc, bool is_in_tiny_cc,
bool is_duration_set, bool is_duration_set,
bool is_access_restricted, bool is_access_restricted,
bool is_contra_flow, TravelMode travel_mode,
bool is_split) bool is_split)
: start(start), target(target), type(type), direction(direction), speed(speed), : start(start), target(target), direction(direction), speed(speed),
name_id(name_id), is_roundabout(is_roundabout), is_in_tiny_cc(is_in_tiny_cc), name_id(name_id), is_roundabout(is_roundabout), is_in_tiny_cc(is_in_tiny_cc),
is_duration_set(is_duration_set), is_access_restricted(is_access_restricted), is_duration_set(is_duration_set), is_access_restricted(is_access_restricted),
is_contra_flow(is_contra_flow), is_split(is_split) travel_mode(travel_mode), is_split(is_split)
{ {
BOOST_ASSERT(0 <= type);
} }
// necessary static util functions for stxxl's sorting // necessary static util functions for stxxl's sorting
static InternalExtractorEdge min_value() static InternalExtractorEdge min_value()
{ {
return InternalExtractorEdge(0, 0, 0, 0, 0, 0, false, false, false, false, false, false); return InternalExtractorEdge(0, 0, 0, 0, 0, false, false, false, false, TRAVEL_MODE_INACCESSIBLE, false);
} }
static InternalExtractorEdge max_value() static InternalExtractorEdge max_value()
{ {
return InternalExtractorEdge( return InternalExtractorEdge(
SPECIAL_NODEID, SPECIAL_NODEID, 0, 0, 0, 0, false, false, false, false, false, false); SPECIAL_NODEID, SPECIAL_NODEID, 0, 0, 0, false, false, false, false, TRAVEL_MODE_INACCESSIBLE, false);
} }
NodeID start; NodeID start;
NodeID target; NodeID target;
short type;
short direction; short direction;
double speed; double speed;
unsigned name_id; unsigned name_id;
@ -83,7 +81,7 @@ struct InternalExtractorEdge
bool is_in_tiny_cc; bool is_in_tiny_cc;
bool is_duration_set; bool is_duration_set;
bool is_access_restricted; bool is_access_restricted;
bool is_contra_flow; TravelMode travel_mode : 4;
bool is_split; bool is_split;
FixedPointCoordinate source_coordinate; FixedPointCoordinate source_coordinate;

View File

@ -76,16 +76,17 @@ void ScriptingEnvironment::initLuaState(lua_State* lua_state)
// .def(luabind::constructor<>()) // .def(luabind::constructor<>())
.def_readonly("id", &ExtractionWay::id) .def_readonly("id", &ExtractionWay::id)
.def_readwrite("name", &ExtractionWay::name) .def_readwrite("name", &ExtractionWay::name)
.def_readwrite("speed", &ExtractionWay::speed) .def_readwrite("forward_speed", &ExtractionWay::forward_speed)
.def_readwrite("backward_speed", &ExtractionWay::backward_speed) .def_readwrite("backward_speed", &ExtractionWay::backward_speed)
.def_readwrite("duration", &ExtractionWay::duration) .def_readwrite("duration", &ExtractionWay::duration)
.def_readwrite("type", &ExtractionWay::type)
.def_readwrite("access", &ExtractionWay::access) .def_readwrite("access", &ExtractionWay::access)
.def_readwrite("roundabout", &ExtractionWay::roundabout) .def_readwrite("roundabout", &ExtractionWay::roundabout)
.def_readwrite("is_access_restricted", &ExtractionWay::isAccessRestricted) .def_readwrite("is_access_restricted", &ExtractionWay::isAccessRestricted)
.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) .property("direction", &ExtractionWay::get_direction, &ExtractionWay::set_direction)
.property("forward_mode", &ExtractionWay::get_forward_mode, &ExtractionWay::set_forward_mode)
.property("backward_mode", &ExtractionWay::get_backward_mode, &ExtractionWay::set_backward_mode)
.enum_("constants")[ .enum_("constants")[
luabind::value("notSure", 0), luabind::value("notSure", 0),
luabind::value("oneway", 1), luabind::value("oneway", 1),

View File

@ -6,7 +6,7 @@ require 'sys/proctable'
BUILD_FOLDER = 'build' BUILD_FOLDER = 'build'
DATA_FOLDER = 'sandbox' DATA_FOLDER = 'sandbox'
PROFILE = 'examples/postgis' PROFILE = 'bicycle'
OSRM_PORT = 5000 OSRM_PORT = 5000
PROFILES_FOLDER = '../profiles' PROFILES_FOLDER = '../profiles'

View File

@ -227,6 +227,8 @@ template <class DataFacadeT> class BasicRoutingInterface
BOOST_ASSERT_MSG(!ed.shortcut, "original edge flagged as shortcut"); BOOST_ASSERT_MSG(!ed.shortcut, "original edge flagged as shortcut");
unsigned name_index = facade->GetNameIndexFromEdgeID(ed.id); unsigned name_index = facade->GetNameIndexFromEdgeID(ed.id);
const TurnInstruction turn_instruction = facade->GetTurnInstructionForEdgeID(ed.id); const TurnInstruction turn_instruction = facade->GetTurnInstructionForEdgeID(ed.id);
const TravelMode travel_mode = facade->GetTravelModeForEdgeID(ed.id);
if (!facade->EdgeIsCompressed(ed.id)) if (!facade->EdgeIsCompressed(ed.id))
{ {
@ -234,7 +236,8 @@ template <class DataFacadeT> class BasicRoutingInterface
unpacked_path.emplace_back(facade->GetGeometryIndexForEdgeID(ed.id), unpacked_path.emplace_back(facade->GetGeometryIndexForEdgeID(ed.id),
name_index, name_index,
turn_instruction, turn_instruction,
ed.distance); ed.distance,
travel_mode);
} }
else else
{ {
@ -255,7 +258,7 @@ template <class DataFacadeT> class BasicRoutingInterface
BOOST_ASSERT(start_index <= end_index); BOOST_ASSERT(start_index <= end_index);
for (std::size_t i = start_index; i < end_index; ++i) for (std::size_t i = start_index; i < end_index; ++i)
{ {
unpacked_path.emplace_back(id_vector[i], name_index, TurnInstruction::NoTurn, 0); unpacked_path.emplace_back(id_vector[i], name_index, TurnInstruction::NoTurn, 0, travel_mode);
} }
unpacked_path.back().turn_instruction = turn_instruction; unpacked_path.back().turn_instruction = turn_instruction;
unpacked_path.back().segment_duration = ed.distance; unpacked_path.back().segment_duration = ed.distance;
@ -298,10 +301,12 @@ template <class DataFacadeT> class BasicRoutingInterface
for (std::size_t i = start_index; i != end_index; (start_index < end_index ? ++i : --i)) for (std::size_t i = start_index; i != end_index; (start_index < end_index ? ++i : --i))
{ {
BOOST_ASSERT(i < id_vector.size()); BOOST_ASSERT(i < id_vector.size());
BOOST_ASSERT(phantom_node_pair.target_phantom.forward_travel_mode>0 );
unpacked_path.emplace_back(PathData{id_vector[i], unpacked_path.emplace_back(PathData{id_vector[i],
phantom_node_pair.target_phantom.name_id, phantom_node_pair.target_phantom.name_id,
TurnInstruction::NoTurn, TurnInstruction::NoTurn,
0}); 0,
phantom_node_pair.target_phantom.forward_travel_mode});
} }
} }

View File

@ -92,6 +92,8 @@ template <class EdgeDataT> class BaseDataFacade
virtual TurnInstruction GetTurnInstructionForEdgeID(const unsigned id) const = 0; virtual TurnInstruction GetTurnInstructionForEdgeID(const unsigned id) const = 0;
virtual TravelMode GetTravelModeForEdgeID(const unsigned id) const = 0;
virtual bool LocateClosestEndPointForCoordinate(const FixedPointCoordinate &input_coordinate, virtual bool LocateClosestEndPointForCoordinate(const FixedPointCoordinate &input_coordinate,
FixedPointCoordinate &result, FixedPointCoordinate &result,
const unsigned zoom_level = 18) = 0; const unsigned zoom_level = 18) = 0;

View File

@ -66,6 +66,7 @@ template <class EdgeDataT> class InternalDataFacade : public BaseDataFacade<Edge
ShM<NodeID, false>::vector m_via_node_list; ShM<NodeID, false>::vector m_via_node_list;
ShM<unsigned, false>::vector m_name_ID_list; ShM<unsigned, false>::vector m_name_ID_list;
ShM<TurnInstruction, false>::vector m_turn_instruction_list; ShM<TurnInstruction, false>::vector m_turn_instruction_list;
ShM<TravelMode, false>::vector m_travel_mode_list;
ShM<char, false>::vector m_names_char_list; ShM<char, false>::vector m_names_char_list;
ShM<bool, false>::vector m_egde_is_compressed; ShM<bool, false>::vector m_egde_is_compressed;
ShM<unsigned, false>::vector m_geometry_indices; ShM<unsigned, false>::vector m_geometry_indices;
@ -145,6 +146,7 @@ template <class EdgeDataT> class InternalDataFacade : public BaseDataFacade<Edge
m_via_node_list.resize(number_of_edges); m_via_node_list.resize(number_of_edges);
m_name_ID_list.resize(number_of_edges); m_name_ID_list.resize(number_of_edges);
m_turn_instruction_list.resize(number_of_edges); m_turn_instruction_list.resize(number_of_edges);
m_travel_mode_list.resize(number_of_edges);
m_egde_is_compressed.resize(number_of_edges); m_egde_is_compressed.resize(number_of_edges);
unsigned compressed = 0; unsigned compressed = 0;
@ -156,6 +158,7 @@ template <class EdgeDataT> class InternalDataFacade : public BaseDataFacade<Edge
m_via_node_list[i] = current_edge_data.via_node; m_via_node_list[i] = current_edge_data.via_node;
m_name_ID_list[i] = current_edge_data.name_id; m_name_ID_list[i] = current_edge_data.name_id;
m_turn_instruction_list[i] = current_edge_data.turn_instruction; m_turn_instruction_list[i] = current_edge_data.turn_instruction;
m_travel_mode_list[i] = current_edge_data.travel_mode;
m_egde_is_compressed[i] = current_edge_data.compressed_geometry; m_egde_is_compressed[i] = current_edge_data.compressed_geometry;
if (m_egde_is_compressed[i]) if (m_egde_is_compressed[i])
{ {
@ -356,6 +359,11 @@ template <class EdgeDataT> class InternalDataFacade : public BaseDataFacade<Edge
return m_turn_instruction_list.at(id); return m_turn_instruction_list.at(id);
} }
TravelMode GetTravelModeForEdgeID(const unsigned id) const
{
return m_travel_mode_list.at(id);
}
bool LocateClosestEndPointForCoordinate(const FixedPointCoordinate &input_coordinate, bool LocateClosestEndPointForCoordinate(const FixedPointCoordinate &input_coordinate,
FixedPointCoordinate &result, FixedPointCoordinate &result,
const unsigned zoom_level = 18) final const unsigned zoom_level = 18) final

View File

@ -77,6 +77,7 @@ template <class EdgeDataT> class SharedDataFacade : public BaseDataFacade<EdgeDa
ShM<NodeID, true>::vector m_via_node_list; ShM<NodeID, true>::vector m_via_node_list;
ShM<unsigned, true>::vector m_name_ID_list; ShM<unsigned, true>::vector m_name_ID_list;
ShM<TurnInstruction, true>::vector m_turn_instruction_list; ShM<TurnInstruction, true>::vector m_turn_instruction_list;
ShM<TravelMode, true>::vector m_travel_mode_list;
ShM<char, true>::vector m_names_char_list; ShM<char, true>::vector m_names_char_list;
ShM<unsigned, true>::vector m_name_begin_indices; ShM<unsigned, true>::vector m_name_begin_indices;
ShM<bool, true>::vector m_egde_is_compressed; ShM<bool, true>::vector m_egde_is_compressed;
@ -346,6 +347,11 @@ template <class EdgeDataT> class SharedDataFacade : public BaseDataFacade<EdgeDa
return m_turn_instruction_list.at(id); return m_turn_instruction_list.at(id);
} }
TravelMode GetTravelModeForEdgeID(const unsigned id) const
{
return m_travel_mode_list.at(id);
}
bool LocateClosestEndPointForCoordinate(const FixedPointCoordinate &input_coordinate, bool LocateClosestEndPointForCoordinate(const FixedPointCoordinate &input_coordinate,
FixedPointCoordinate &result, FixedPointCoordinate &result,
const unsigned zoom_level = 18) final const unsigned zoom_level = 18) final

View File

@ -109,7 +109,9 @@ class LinearSearchNN
e.reverse_offset, e.reverse_offset,
e.packed_geometry_id, e.packed_geometry_id,
nearest, nearest,
e.fwd_segment_position}; e.fwd_segment_position,
e.forward_travel_mode,
e.backward_travel_mode};
nearest_edge = e; nearest_edge = e;
} }
} }

View File

@ -126,11 +126,10 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &input_stream,
edge_list.reserve(m); edge_list.reserve(m);
EdgeWeight weight; EdgeWeight weight;
short type;
NodeID nameID; NodeID nameID;
int length; int length;
bool is_roundabout, ignore_in_grid, is_access_restricted, is_contra_flow, is_split; bool is_roundabout, ignore_in_grid, is_access_restricted, is_split;
TravelMode travel_mode;
for (EdgeID i = 0; i < m; ++i) for (EdgeID i = 0; i < m; ++i)
{ {
input_stream.read((char *)&source, sizeof(unsigned)); input_stream.read((char *)&source, sizeof(unsigned));
@ -138,12 +137,11 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &input_stream,
input_stream.read((char *)&length, sizeof(int)); input_stream.read((char *)&length, sizeof(int));
input_stream.read((char *)&dir, sizeof(short)); input_stream.read((char *)&dir, sizeof(short));
input_stream.read((char *)&weight, sizeof(int)); input_stream.read((char *)&weight, sizeof(int));
input_stream.read((char *)&type, sizeof(short));
input_stream.read((char *)&nameID, sizeof(unsigned)); input_stream.read((char *)&nameID, sizeof(unsigned));
input_stream.read((char *)&is_roundabout, sizeof(bool)); input_stream.read((char *)&is_roundabout, sizeof(bool));
input_stream.read((char *)&ignore_in_grid, sizeof(bool)); input_stream.read((char *)&ignore_in_grid, sizeof(bool));
input_stream.read((char *)&is_access_restricted, sizeof(bool)); input_stream.read((char *)&is_access_restricted, sizeof(bool));
input_stream.read((char *)&is_contra_flow, sizeof(bool)); input_stream.read((char *)&travel_mode, sizeof(TravelMode));
input_stream.read((char *)&is_split, sizeof(bool)); input_stream.read((char *)&is_split, sizeof(bool));
BOOST_ASSERT_MSG(length > 0, "loaded null length edge"); BOOST_ASSERT_MSG(length > 0, "loaded null length edge");
@ -161,8 +159,6 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &input_stream,
forward = false; forward = false;
} }
BOOST_ASSERT(type >= 0);
// translate the external NodeIDs to internal IDs // translate the external NodeIDs to internal IDs
auto internal_id_iter = ext_to_int_id_map.find(source); auto internal_id_iter = ext_to_int_id_map.find(source);
if (ext_to_int_id_map.find(source) == ext_to_int_id_map.end()) if (ext_to_int_id_map.find(source) == ext_to_int_id_map.end())
@ -196,11 +192,10 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &input_stream,
weight, weight,
forward, forward,
backward, backward,
type,
is_roundabout, is_roundabout,
ignore_in_grid, ignore_in_grid,
is_access_restricted, is_access_restricted,
is_contra_flow, travel_mode,
is_split); is_split);
} }
@ -303,10 +298,10 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &input_stream,
edge_list.reserve(m); edge_list.reserve(m);
EdgeWeight weight; EdgeWeight weight;
short type;
NodeID nameID; NodeID nameID;
int length; int length;
bool is_roundabout, ignore_in_grid, is_access_restricted, is_contra_flow, is_split; bool is_roundabout, ignore_in_grid, is_access_restricted, is_split;
TravelMode travel_mode;
for (EdgeID i = 0; i < m; ++i) for (EdgeID i = 0; i < m; ++i)
{ {
@ -315,20 +310,17 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &input_stream,
input_stream.read((char *)&length, sizeof(int)); input_stream.read((char *)&length, sizeof(int));
input_stream.read((char *)&dir, sizeof(short)); input_stream.read((char *)&dir, sizeof(short));
input_stream.read((char *)&weight, sizeof(int)); input_stream.read((char *)&weight, sizeof(int));
input_stream.read((char *)&type, sizeof(short));
input_stream.read((char *)&nameID, sizeof(unsigned)); input_stream.read((char *)&nameID, sizeof(unsigned));
input_stream.read((char *)&is_roundabout, sizeof(bool)); input_stream.read((char *)&is_roundabout, sizeof(bool));
input_stream.read((char *)&ignore_in_grid, sizeof(bool)); input_stream.read((char *)&ignore_in_grid, sizeof(bool));
input_stream.read((char *)&is_access_restricted, sizeof(bool)); input_stream.read((char *)&is_access_restricted, sizeof(bool));
input_stream.read((char *)&is_contra_flow, sizeof(bool)); input_stream.read((char *)&travel_mode, sizeof(TravelMode));
input_stream.read((char *)&is_split, sizeof(bool)); input_stream.read((char *)&is_split, sizeof(bool));
BOOST_ASSERT_MSG(length > 0, "loaded null length edge"); BOOST_ASSERT_MSG(length > 0, "loaded null length edge");
BOOST_ASSERT_MSG(weight > 0, "loaded null weight"); BOOST_ASSERT_MSG(weight > 0, "loaded null weight");
BOOST_ASSERT_MSG(0 <= dir && dir <= 2, "loaded bogus direction"); BOOST_ASSERT_MSG(0 <= dir && dir <= 2, "loaded bogus direction");
BOOST_ASSERT(type >= 0);
// translate the external NodeIDs to internal IDs // translate the external NodeIDs to internal IDs
auto internal_id_iter = ext_to_int_id_map.find(source); auto internal_id_iter = ext_to_int_id_map.find(source);
if (ext_to_int_id_map.find(source) == ext_to_int_id_map.end()) if (ext_to_int_id_map.find(source) == ext_to_int_id_map.end())

View File

@ -1,89 +1,177 @@
@routing @bicycle @mode @routing @bicycle @mode
Feature: Bike - Mode flag Feature: Bike - Mode flag
Background: # bicycle modes:
Given the profile "bicycle" # 1 bike
# 2 pushing
# 3 ferry
# 4 train
@todo Background:
Given the profile "bicycle"
Scenario: Bike - Mode when using a ferry Scenario: Bike - Mode when using a ferry
Given the node map
| a | b | |
| | c | d |
And the ways
| nodes | highway | route | duration |
| ab | primary | | |
| bc | | ferry | 0:01 |
| cd | primary | | |
When I route I should get
| 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 |
Scenario: Bike - Mode when using a train
Given the node map
| a | b | |
| | c | d |
And the ways
| nodes | highway | railway | bicycle |
| ab | primary | | |
| bc | | train | yes |
| cd | primary | | |
When I route I should get
| from | to | route | turns | modes |
| a | d | ab,bc,cd | head,right,left,destination | 1,4,1 |
| d | a | cd,bc,ab | head,right,left,destination | 1,4,1 |
| c | a | bc,ab | head,left,destination | 4,1 |
| d | b | cd,bc | head,right,destination | 1,4 |
| a | c | ab,bc | head,right,destination | 1,4 |
| b | d | bc,cd | head,left,destination | 4,1 |
Scenario: Bike - Mode when pushing bike against oneways
Given the node map
| a | b | |
| | c | d |
And the ways
| nodes | highway | oneway |
| ab | primary | |
| bc | primary | yes |
| cd | primary | |
When I route I should get
| 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,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,1 |
| b | d | bc,cd | head,left,destination | 1,1 |
Scenario: Bike - Mode when pushing on pedestrain streets
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 | 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 |
Scenario: Bike - Mode when pushing on pedestrain areas
Given the node map
| a | b | | |
| | c | d | f |
And the ways
| nodes | highway | area |
| ab | primary | |
| bcd | pedestrian | yes |
| df | primary | |
When I route I should get
| from | to | route | modes |
| a | f | ab,bcd,df | 1,2,1 |
| f | a | df,bcd,ab | 1,2,1 |
| d | a | bcd,ab | 2,1 |
| f | b | df,bcd | 1,2 |
| a | d | ab,bcd | 1,2 |
| b | f | bcd,df | 2,1 |
Scenario: Bike - Mode when pushing on steps
Given the node map
| a | b | | |
| | c | d | f |
And the ways
| nodes | highway |
| ab | primary |
| bc | steps |
| cd | primary |
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 |
Scenario: Bike - Mode when bicycle=dismount
Given the node map
| a | b | | |
| | c | d | f |
And the ways
| nodes | highway | bicycle |
| ab | primary | |
| bc | primary | dismount |
| cd | primary | |
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 |
Scenario: Bicycle - Modes when starting on forward oneway
Given the node map Given the node map
| a | b | | | a | b |
| | c | d |
And the ways And the ways
| nodes | highway | route | duration | | nodes | oneway |
| ab | primary | | | | ab | yes |
| bc | | ferry | 0:01 |
| cd | primary | | |
When I route I should get When I route I should get
| from | to | route | turns | modes | | from | to | route | modes |
| a | d | ab,bc,cd | head,right,left, destination | bike,ferry,bike | | a | b | ab | 1 |
| d | a | cd,bc,ab | head,right,left, destination | bike,ferry,bike | | b | a | ab | 2 |
| 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 |
@todo Scenario: Bicycle - Modes when starting on reverse oneway
Scenario: Bike - Mode when pushing bike against oneways
Given the node map Given the node map
| a | b | | | a | b |
| | c | d |
And the ways And the ways
| nodes | highway | oneway | | nodes | oneway |
| ab | primary | | | ab | -1 |
| bc | primary | yes |
| cd | primary | |
When I route I should get When I route I should get
| from | to | route | turns | modes | | from | to | route | modes |
| a | d | ab,bc,cd | head,right,left,destination | bike,push,bike | | a | b | ab | 2 |
| d | a | cd,bc,ab | head,right,left,destination | bike,push,bike | | b | a | ab | 1 |
| 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 |
@todo
Scenario: Bike - Mode when pushing on pedestrain streets
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 | 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 |
@todo
Scenario: Bike - Mode when pushing on pedestrain areas
Given the node map
| a | b | | |
| | c | d | f |
And the ways
| nodes | highway | area |
| ab | primary | |
| bcd | pedestrian | yes |
| 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 |

View File

@ -4,9 +4,9 @@ Feature: Bike - Accessability of different way types
Background: Background:
Given the profile "bicycle" Given the profile "bicycle"
Given the shortcuts Given the shortcuts
| key | value | | key | value |
| bike | 49s ~20% | | bike | 15 km/h ~20% |
| foot | 121s ~20% | | foot | 5 km/h ~20% |
Scenario: Bike - Pushing bikes on pedestrian-only ways Scenario: Bike - Pushing bikes on pedestrian-only ways
Then routability should be Then routability should be
@ -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,8 @@ 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 |

View File

@ -17,12 +17,12 @@ Feature: Car - Handle ferry routes
| efg | primary | | | | efg | primary | | |
When I route I should get When I route I should get
| from | to | route | | from | to | route | modes |
| a | g | abc,cde,efg | | a | g | abc,cde,efg | 1,2,1 |
| b | f | abc,cde,efg | | b | f | abc,cde,efg | 1,2,1 |
| e | c | cde | | e | c | cde | 2 |
| e | b | cde,abc | | e | b | cde,abc | 2,1 |
| e | a | cde,abc | | e | a | cde,abc | 2,1 |
| c | e | cde | | c | e | cde | 2 |
| c | f | cde,efg | | c | f | cde,efg | 2,1 |
| c | g | cde,efg | | c | g | cde,efg | 2,1 |

View File

@ -38,14 +38,14 @@ OSRM will use 4/5 of the projected free-flow speed.
Given a grid size of 100 meters Given a grid size of 100 meters
Then routability should be Then routability should be
| highway | maxspeed | maxspeed:forward | maxspeed:backward | forw | backw | | highway | maxspeed | maxspeed:forward | maxspeed:backward | forw | backw |
| primary | | | | 51 km/h | 51 km/h | | primary | | | | 51 km/h | 51 km/h |
| primary | 60 | | | 48 km/h | 48 km/h | | primary | 60 | | | 48 km/h | 48 km/h |
| primary | | 60 | | 48 km/h | 65 km/h | | primary | | 60 | | 48 km/h | 51 km/h |
| primary | | | 60 | 51 km/h | 48 km/h | | primary | | | 60 | 51 km/h | 48 km/h |
| primary | 15 | 60 | | 48 km/h | 15 km/h +- 1 | | primary | 15 | 60 | | 48 km/h | 12 km/h |
| primary | 15 | | 60 | 12 km/h +- 1| 48 km/h | | primary | 15 | | 60 | 12 km/h | 48 km/h |
| primary | 15 | 30 | 60 | 24 km/h | 48 km/h | | primary | 15 | 30 | 60 | 24 km/h | 48 km/h |
Scenario: Car - Maxspeed should not allow routing on unroutable ways Scenario: Car - Maxspeed should not allow routing on unroutable ways
Then routability should be Then routability should be

View File

@ -17,15 +17,15 @@ Feature: Foot - Handle ferry routes
| efg | primary | | | | efg | primary | | |
When I route I should get When I route I should get
| from | to | route | | from | to | route | modes |
| a | g | abc,cde,efg | | a | g | abc,cde,efg | 1,2,1 |
| b | f | abc,cde,efg | | b | f | abc,cde,efg | 1,2,1 |
| e | c | cde | | e | c | cde | 2 |
| e | b | cde,abc | | e | b | cde,abc | 2,1 |
| e | a | cde,abc | | e | a | cde,abc | 2,1 |
| c | e | cde | | c | e | cde | 2 |
| c | f | cde,efg | | c | f | cde,efg | 2,1 |
| c | g | cde,efg | | c | g | cde,efg | 2,1 |
Scenario: Foot - Ferry duration, single node Scenario: Foot - Ferry duration, single node
Given the node map Given the node map

View File

@ -54,11 +54,11 @@ Then /^routability should be$/ do |table|
want = shortcuts_hash[row[direction]] || row[direction] #expand shortcuts want = shortcuts_hash[row[direction]] || row[direction] #expand shortcuts
case want case want
when '', 'x' when '', 'x'
output_row[direction] = result[direction][:status].to_s output_row[direction] = result[direction][:status] ? result[direction][:status].to_s : ''
when /^\d+s/ when /^\d+s/
output_row[direction] = "#{result[direction][:time]}s" output_row[direction] = result[direction][:time] ? "#{result[direction][:time]}s" : ''
when /^\d+ km\/h/ when /^\d+ km\/h/
output_row[direction] = "#{result[direction][:speed]} km/h" output_row[direction] = result[direction][:speed] ? "#{result[direction][:speed]} km/h" : ''
else else
raise "*** Unknown expectation format: #{want}" raise "*** Unknown expectation format: #{want}"
end end

View File

@ -104,22 +104,22 @@ When /^I route I should get$/ do |table|
end end
end end
if table.headers.include? 'bearing' if table.headers.include? 'bearing'
got['bearing'] = bearings got['bearing'] = instructions ? bearings : ''
end end
if table.headers.include? 'compass' if table.headers.include? 'compass'
got['compass'] = compasses got['compass'] = instructions ? compasses : ''
end end
if table.headers.include? 'turns' if table.headers.include? 'turns'
got['turns'] = turns got['turns'] = instructions ? turns : ''
end end
if table.headers.include? 'modes' if table.headers.include? 'modes'
got['modes'] = modes got['modes'] = instructions ? modes : ''
end end
if table.headers.include? 'times' if table.headers.include? 'times'
got['times'] = times got['times'] = instructions ? times : ''
end end
if table.headers.include? 'distances' if table.headers.include? 'distances'
got['distances'] = distances got['distances'] = instructions ? distances : ''
end end
end end
end end

View File

@ -1,26 +1,227 @@
@routing @testbot @mode @routing @testbot @mode
Feature: Testbot - Mode flag Feature: Testbot - Travel mode
# testbot modes:
# 1 normal
# 2 route
# 3 river downstream
# 4 river upstream
# 5 steps down
# 6 steps up
Background: Background:
Given the profile "testbot" Given the profile "testbot"
@todo Scenario: Testbot - Modes in each direction, different forward/backward speeds
Scenario: Bike - Mode
Given the node map Given the node map
| a | b | | | | 0 | 1 | |
| | c | d | | a | | | b |
And the ways And the ways
| nodes | highway | oneway |
| ab | river | |
When I route I should get
| from | to | route | modes |
| a | 0 | ab | 3 |
| a | b | ab | 3 |
| 0 | 1 | ab | 3 |
| 0 | b | ab | 3 |
| b | 1 | ab | 4 |
| b | a | ab | 4 |
| 1 | 0 | ab | 4 |
| 1 | a | ab | 4 |
Scenario: Testbot - Modes in each direction, same forward/backward speeds
Given the node map
| | 0 | 1 | |
| a | | | b |
And the ways
| nodes | highway |
| ab | steps |
When I route I should get
| from | to | route | modes | time |
| 0 | 1 | ab | 5 | 60s +-1 |
| 1 | 0 | ab | 6 | 60s +-1 |
@oneway
Scenario: Testbot - Modes for oneway, different forward/backward speeds
Given the node map
| a | b |
And the ways
| nodes | highway | oneway |
| ab | river | yes |
When I route I should get
| from | to | route | modes |
| a | b | ab | 3 |
| b | a | | |
@oneway
Scenario: Testbot - Modes for oneway, same forward/backward speeds
Given the node map
| a | b |
And the ways
| nodes | highway | oneway |
| ab | steps | yes |
When I route I should get
| from | to | route | modes |
| a | b | ab | 5 |
| b | a | | |
@oneway
Scenario: Testbot - Modes for reverse oneway, different forward/backward speeds
Given the node map
| a | b |
And the ways
| nodes | highway | oneway |
| ab | river | -1 |
When I route I should get
| from | to | route | modes |
| a | b | | |
| b | a | ab | 4 |
@oneway
Scenario: Testbot - Modes for reverse oneway, same forward/backward speeds
Given the node map
| a | b |
And the ways
| nodes | highway | oneway |
| ab | steps | -1 |
When I route I should get
| from | to | route | modes |
| a | b | | |
| b | a | ab | 6 |
@via
Scenario: Testbot - Mode should be set at via points
Given the node map
| a | 1 | b |
And the ways
| nodes | highway |
| ab | river |
When I route I should get
| waypoints | route | modes | turns |
| a,1,b | ab,ab | 3,3 | head,via,destination |
| b,1,a | ab,ab | 4,4 | head,via,destination |
Scenario: Testbot - Starting at a tricky node
Given the node map
| | a | | | |
| | | | b | c |
And the ways
| nodes | highway |
| ab | river |
| bc | primary |
When I route I should get
| from | to | route | modes |
| b | a | ab | 4 |
Scenario: Testbot - Mode changes on straight way without name change
Given the node map
| a | 1 | b | 2 | c |
And the ways
| nodes | highway | name |
| ab | primary | Avenue |
| bc | river | Avenue |
When I route I should get
| from | to | route | modes | turns |
| a | c | Avenue,Avenue | 1,3 | head,straight,destination |
| c | a | Avenue,Avenue | 4,1 | head,straight,destination |
| 1 | 2 | Avenue,Avenue | 1,3 | head,straight,destination |
| 2 | 1 | Avenue,Avenue | 4,1 | head,straight,destination |
Scenario: Testbot - Mode for routes
Given the node map
| a | b | | | |
| | c | d | e | f |
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
| 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, triangle map
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 - River in the middle
Given the node map
| a | b | c | | |
| | | d | | |
| | | e | f | g |
And the ways
| nodes | highway |
| abc | primary |
| cde | river |
| efg | primary |
When I route I should get When I route I should get
| from | to | route | turns | modes | | from | to | route | modes |
| a | d | ab,bc,cd | head,right,left,destination | bot,ferry,bot | | a | g | abc,cde,efg | 1,3,1 |
| d | a | cd,bc,ab | head,right left,destination | bot,ferry,bot | | b | f | abc,cde,efg | 1,3,1 |
| c | a | bc,ab | head,left,destination | ferry,bot | | e | c | cde | 4 |
| d | b | cd,bc | head,right,destination | bot,ferry | | e | b | cde,abc | 4,1 |
| a | c | ab,bc | head,right,destination | bot,ferry | | e | a | cde,abc | 4,1 |
| b | d | bc,cd | head,left,destination | ferry,bot | | c | e | cde | 3 |
| c | f | cde,efg | 3,1 |
| c | g | cde,efg | 3,1 |

View File

@ -42,3 +42,57 @@ Feature: Testbot - oneways
| g | f | gh,ha,ab,bc,cd,de,ef | | g | f | gh,ha,ab,bc,cd,de,ef |
| h | g | ha,ab,bc,cd,de,ef,fg | | h | g | ha,ab,bc,cd,de,ef,fg |
| a | h | ab,bc,cd,de,ef,fg,gh | | a | h | ab,bc,cd,de,ef,fg,gh |
Scenario: Testbot - Simple oneway
Then routability should be
| highway | foot | oneway | forw | backw |
| primary | no | yes | x | |
Scenario: Simple reverse oneway
Then routability should be
| highway | foot | oneway | forw | backw |
| primary | no | -1 | | x |
Scenario: Testbot - Around the Block
Given the node map
| a | b |
| d | c |
And the ways
| nodes | oneway | foot |
| ab | yes | no |
| bc | | no |
| cd | | no |
| da | | no |
When I route I should get
| from | to | route |
| a | b | ab |
| b | a | bc,cd,da |
Scenario: Testbot - Handle various oneway tag values
Then routability should be
| foot | oneway | forw | backw |
| no | | x | x |
| no | nonsense | x | x |
| no | no | x | x |
| no | false | x | x |
| no | 0 | x | x |
| no | yes | x | |
| no | true | x | |
| no | 1 | x | |
| no | -1 | | x |
Scenario: Testbot - Two consecutive oneways
Given the node map
| a | b | c |
And the ways
| nodes | oneway |
| ab | yes |
| bc | yes |
When I route I should get
| from | to | route |
| a | c | ab,bc |

View File

@ -1,4 +1,5 @@
require("lib/access") require("lib/access")
require("lib/maxspeed")
-- Begin of globals -- Begin of globals
barrier_whitelist = { [""] = true, ["cycle_barrier"] = true, ["bollard"] = true, ["entrance"] = true, ["cattle_grid"] = true, ["border_control"] = true, ["toll_booth"] = true, ["sally_port"] = true, ["gate"] = true, ["no"] = true } barrier_whitelist = { [""] = true, ["cycle_barrier"] = true, ["bollard"] = true, ["entrance"] = true, ["cattle_grid"] = true, ["border_control"] = true, ["toll_booth"] = true, ["sally_port"] = true, ["gate"] = true, ["no"] = true }
@ -94,7 +95,13 @@ u_turn_penalty = 20
use_turn_restrictions = false use_turn_restrictions = false
turn_penalty = 60 turn_penalty = 60
turn_bias = 1.4 turn_bias = 1.4
-- End of globals
--modes
mode_normal = 1
mode_pushing = 2
mode_ferry = 3
mode_train = 4
local function parse_maxspeed(source) local function parse_maxspeed(source)
@ -161,18 +168,18 @@ function way_function (way)
(not man_made or man_made=='') and (not man_made or man_made=='') and
(not public_transport or public_transport=='') (not public_transport or public_transport=='')
then then
return 0 return
end end
-- don't route on ways or railways that are still under construction -- don't route on ways or railways that are still under construction
if highway=='construction' or railway=='construction' then if highway=='construction' or railway=='construction' then
return 0 return
end end
-- access -- access
local access = Access.find_access_tag(way, access_tags_hierachy) local access = Access.find_access_tag(way, access_tags_hierachy)
if access_tag_blacklist[access] then if access_tag_blacklist[access] then
return 0 return
end end
-- other tags -- other tags
@ -193,6 +200,7 @@ 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 bicycle = way.tags:Find("bicycle")
-- name -- name
if "" ~= ref and "" ~= name then if "" ~= ref and "" ~= name then
@ -215,126 +223,152 @@ function way_function (way)
-- 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)
way.direction = Way.bidirectional way.forward_mode = mode_ferry
way.backward_mode = mode_ferry
way.ignore_in_grid = true way.ignore_in_grid = true
if durationIsValid(duration) then if durationIsValid(duration) then
way.duration = math.max( 1, parseDuration(duration) ) way.duration = math.max( 1, parseDuration(duration) )
else else
way.speed = route_speeds[route] way.forward_speed = route_speeds[route]
way.backward_speed = route_speeds[route]
end end
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.forward_speed = platform_speeds[railway]
way.backward_speed = platform_speeds[railway]
elseif platform_speeds[public_transport] then elseif platform_speeds[public_transport] then
-- public_transport platforms (new tagging platform) -- public_transport platforms (new tagging platform)
way.speed = platform_speeds[public_transport] way.forward_speed = platform_speeds[public_transport]
way.backward_speed = platform_speeds[public_transport]
elseif railway and railway_speeds[railway] then elseif railway and railway_speeds[railway] then
way.forward_mode = mode_train
way.backward_mode = mode_train
-- railways -- railways
if access and access_tag_whitelist[access] then if access and access_tag_whitelist[access] then
way.speed = railway_speeds[railway] way.forward_speed = railway_speeds[railway]
way.direction = Way.bidirectional way.backward_speed = railway_speeds[railway]
end end
elseif amenity and amenity_speeds[amenity] then elseif amenity and amenity_speeds[amenity] then
-- parking areas -- parking areas
way.speed = amenity_speeds[amenity] way.forward_speed = amenity_speeds[amenity]
way.backward_speed = amenity_speeds[amenity]
elseif bicycle_speeds[highway] then elseif bicycle_speeds[highway] then
-- regular ways -- regular ways
way.speed = bicycle_speeds[highway] way.forward_speed = bicycle_speeds[highway]
way.backward_speed = bicycle_speeds[highway]
elseif access and access_tag_whitelist[access] then elseif access and access_tag_whitelist[access] then
-- unknown way, but valid access tag -- unknown way, but valid access tag
way.speed = default_speed way.forward_speed = default_speed
way.backward_speed = default_speed
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' and junction ~= "roundabout" 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.forward_speed = pedestrian_speeds[highway]
way.backward_speed = pedestrian_speeds[highway]
way.forward_mode = mode_pushing
way.backward_mode = mode_pushing
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.forward_speed = man_made_speeds[man_made]
way.backward_speed = man_made_speeds[man_made]
way.forward_mode = mode_pushing
way.backward_mode = mode_pushing
elseif foot == 'yes' then elseif foot == 'yes' then
way.speed = walking_speed way.forward_speed = walking_speed
way.backward_speed = walking_speed
way.forward_mode = mode_pushing
way.backward_mode = mode_pushing
elseif foot_forward == 'yes' then
way.forward_speed = walking_speed
way.forward_mode = mode_pushing
way.backward_mode = 0
elseif foot_backward == 'yes' then
way.forward_speed = walking_speed
way.forward_mode = 0
way.backward_mode = mode_pushing
end end
end end
end end
-- direction -- direction
way.direction = Way.bidirectional
local impliedOneway = false local impliedOneway = false
if junction == "roundabout" or highway == "motorway_link" or highway == "motorway" then if junction == "roundabout" or highway == "motorway_link" or highway == "motorway" then
way.direction = Way.oneway
impliedOneway = true impliedOneway = true
end end
if onewayClass == "yes" or onewayClass == "1" or onewayClass == "true" then if onewayClass == "yes" or onewayClass == "1" or onewayClass == "true" then
way.direction = Way.oneway way.backward_mode = 0
elseif onewayClass == "no" or onewayClass == "0" or onewayClass == "false" then elseif onewayClass == "no" or onewayClass == "0" or onewayClass == "false" then
way.direction = Way.bidirectional -- prevent implied oneway
elseif onewayClass == "-1" then elseif onewayClass == "-1" then
way.direction = Way.opposite way.forward_mode = 0
elseif oneway == "no" or oneway == "0" or oneway == "false" then elseif oneway == "no" or oneway == "0" or oneway == "false" then
way.direction = Way.bidirectional -- prevent implied oneway
elseif cycleway and string.find(cycleway, "opposite") == 1 then elseif cycleway and string.find(cycleway, "opposite") == 1 then
if impliedOneway then if impliedOneway then
way.direction = Way.opposite way.forward_mode = 0
else way.backward_mode = mode_normal
way.direction = Way.bidirectional way.backward_speed = bicycle_speeds["cycleway"]
end end
elseif cycleway_left and cycleway_tags[cycleway_left] and cycleway_right and cycleway_tags[cycleway_right] then elseif cycleway_left and cycleway_tags[cycleway_left] and cycleway_right and cycleway_tags[cycleway_right] then
way.direction = Way.bidirectional -- prevent implied
elseif cycleway_left and cycleway_tags[cycleway_left] then elseif cycleway_left and cycleway_tags[cycleway_left] then
if impliedOneway then if impliedOneway then
way.direction = Way.opposite way.forward_mode = 0
else way.backward_mode = mode_normal
way.direction = Way.bidirectional way.backward_speed = bicycle_speeds["cycleway"]
end end
elseif cycleway_right and cycleway_tags[cycleway_right] then elseif cycleway_right and cycleway_tags[cycleway_right] then
if impliedOneway then if impliedOneway then
way.direction = Way.oneway way.forward_mode = mode_normal
else way.backward_speed = bicycle_speeds["cycleway"]
way.direction = Way.bidirectional way.backward_mode = 0
end end
elseif oneway == "-1" then elseif oneway == "-1" then
way.direction = Way.opposite way.forward_mode = 0
elseif oneway == "yes" or oneway == "1" or oneway == "true" then elseif oneway == "yes" or oneway == "1" or oneway == "true" or impliedOneway then
way.direction = Way.oneway way.backward_mode = 0
end end
-- pushing bikes -- pushing bikes
if bicycle_speeds[highway] or pedestrian_speeds[highway] then if bicycle_speeds[highway] or pedestrian_speeds[highway] then
if foot ~= 'no' then if foot ~= "no" and junction ~= "roundabout" then
if junction ~= "roundabout" then if way.backward_mode == 0 then
if way.direction == Way.oneway then way.backward_speed = walking_speed
way.backward_speed = walking_speed way.backward_mode = mode_pushing
elseif way.direction == Way.opposite then elseif way.forward_mode == 0 then
way.backward_speed = walking_speed way.forward_speed = walking_speed
way.speed = way.speed way.forward_mode = mode_pushing
end
end 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 end
-- cycleways -- cycleways
if cycleway and cycleway_tags[cycleway] then if cycleway and cycleway_tags[cycleway] then
way.speed = bicycle_speeds["cycleway"] way.forward_speed = bicycle_speeds["cycleway"]
elseif cycleway_left and cycleway_tags[cycleway_left] then elseif cycleway_left and cycleway_tags[cycleway_left] then
way.speed = bicycle_speeds["cycleway"] way.forward_speed = bicycle_speeds["cycleway"]
elseif cycleway_right and cycleway_tags[cycleway_right] then elseif cycleway_right and cycleway_tags[cycleway_right] then
way.speed = bicycle_speeds["cycleway"] way.forward_speed = bicycle_speeds["cycleway"]
end
-- dismount
if bicycle == "dismount" then
way.forward_mode = mode_pushing
way.backward_mode = mode_pushing
way.forward_speed = walking_speed
way.backward_speed = walking_speed
end end
-- surfaces -- surfaces
if surface then if surface then
surface_speed = surface_speeds[surface] surface_speed = surface_speeds[surface]
if surface_speed then if surface_speed then
if way.speed > 0 then if way.forward_speed > 0 then
way.speed = surface_speed way.forward_speed = surface_speed
end end
if way.backward_speed > 0 then if way.backward_speed > 0 then
way.backward_speed = surface_speed way.backward_speed = surface_speed
@ -343,26 +377,7 @@ function way_function (way)
end end
-- maxspeed -- maxspeed
-- TODO: maxspeed of backward direction MaxSpeed.limit( way, maxspeed, maxspeed_forward, maxspeed_backward )
if take_minimum_of_speeds then
if maxspeed and maxspeed>0 then
way.speed = math.min(way.speed, maxspeed)
end
end
-- Override speed settings if explicit forward/backward maxspeeds are given
if way.speed > 0 and maxspeed_forward ~= nil and maxspeed_forward > 0 then
if Way.bidirectional == way.direction then
way.backward_speed = way.speed
end
way.speed = maxspeed_forward
end
if maxspeed_backward ~= nil and maxspeed_backward > 0 then
way.backward_speed = maxspeed_backward
end
way.type = 1
return 1
end end
function turn_function (angle) function turn_function (angle)

44
profiles/car.lua Normal file → Executable file
View File

@ -48,6 +48,11 @@ local max = math.max
local speed_reduction = 0.8 local speed_reduction = 0.8
--modes
local mode_normal = 1
local mode_ferry = 2
local function find_access_tag(source,access_tags_hierachy) local function find_access_tag(source,access_tags_hierachy)
for i,v in ipairs(access_tags_hierachy) do for i,v in ipairs(access_tags_hierachy) do
local has_tag = source.tags:Holds(v) local has_tag = source.tags:Holds(v)
@ -169,8 +174,10 @@ function way_function (way)
if durationIsValid(duration) then if durationIsValid(duration) then
way.duration = max( parseDuration(duration), 1 ); way.duration = max( parseDuration(duration), 1 );
end end
way.direction = Way.bidirectional way.forward_mode = mode_ferry
way.speed = route_speed way.backward_mode = mode_ferry
way.forward_speed = route_speed
way.backward_speed = route_speed
end end
-- leave early of this way is not accessible -- leave early of this way is not accessible
@ -178,30 +185,34 @@ function way_function (way)
return return
end end
if way.speed == -1 then if way.forward_speed == -1 then
local highway_speed = speed_profile[highway] local highway_speed = speed_profile[highway]
local max_speed = parse_maxspeed( way.tags:Find("maxspeed") ) local max_speed = parse_maxspeed( way.tags:Find("maxspeed") )
-- Set the avg speed on the way if it is accessible by road class -- Set the avg speed on the way if it is accessible by road class
if highway_speed then if highway_speed then
if max_speed > highway_speed then if max_speed > highway_speed then
way.speed = max_speed way.forward_speed = max_speed
way.backward_speed = max_speed
-- max_speed = math.huge -- max_speed = math.huge
else else
way.speed = highway_speed way.forward_speed = highway_speed
way.backward_speed = highway_speed
end end
else else
-- Set the avg speed on ways that are marked accessible -- Set the avg speed on ways that are marked accessible
if access_tag_whitelist[access] then if access_tag_whitelist[access] then
way.speed = speed_profile["default"] way.forward_speed = speed_profile["default"]
way.backward_speed = speed_profile["default"]
end end
end end
if 0 == max_speed then if 0 == max_speed then
max_speed = math.huge max_speed = math.huge
end end
way.speed = min(way.speed, max_speed) way.forward_speed = min(way.forward_speed, max_speed)
way.backward_speed = min(way.backward_speed, max_speed)
end end
if -1 == way.speed then if -1 == way.forward_speed and -1 == way.backward_speed then
return return
end end
@ -237,17 +248,16 @@ function way_function (way)
end end
-- Set direction according to tags on way -- Set direction according to tags on way
way.direction = Way.bidirectional
if obey_oneway then if obey_oneway then
if oneway == "-1" then if oneway == "-1" then
way.direction = Way.opposite way.forward_mode = 0
elseif oneway == "yes" or elseif oneway == "yes" or
oneway == "1" or oneway == "1" or
oneway == "true" or oneway == "true" or
junction == "roundabout" or junction == "roundabout" or
(highway == "motorway_link" and oneway ~="no") or (highway == "motorway_link" and oneway ~="no") or
(highway == "motorway" and oneway ~= "no") then (highway == "motorway" and oneway ~= "no") then
way.direction = Way.oneway way.backward_mode = 0
end end
end end
@ -255,10 +265,10 @@ function way_function (way)
local maxspeed_forward = parse_maxspeed(way.tags:Find( "maxspeed:forward")) local maxspeed_forward = parse_maxspeed(way.tags:Find( "maxspeed:forward"))
local maxspeed_backward = parse_maxspeed(way.tags:Find( "maxspeed:backward")) local maxspeed_backward = parse_maxspeed(way.tags:Find( "maxspeed:backward"))
if maxspeed_forward > 0 then if maxspeed_forward > 0 then
if Way.bidirectional == way.direction then if 0 ~= way.forward_mode and 0 ~= way.backward_mode then
way.backward_speed = way.speed way.backward_speed = way.forward_speed
end end
way.speed = maxspeed_forward way.forward_speed = maxspeed_forward
end end
if maxspeed_backward > 0 then if maxspeed_backward > 0 then
way.backward_speed = maxspeed_backward way.backward_speed = maxspeed_backward
@ -268,14 +278,12 @@ function way_function (way)
if ignore_in_grid[highway] then if ignore_in_grid[highway] then
way.ignore_in_grid = true way.ignore_in_grid = true
end end
way.type = 1
-- scale speeds to get better avg driving times -- scale speeds to get better avg driving times
way.speed = way.speed * speed_reduction way.forward_speed = way.forward_speed * speed_reduction
if maxspeed_backward > 0 then if way.backward_speed > 0 then
way.backward_speed = way.backward_speed*speed_reduction way.backward_speed = way.backward_speed*speed_reduction
end end
return
end end
-- These are wrappers to parse vectors of nodes and ways and thus to speed up any tracing JIT -- These are wrappers to parse vectors of nodes and ways and thus to speed up any tracing JIT

View File

@ -65,11 +65,11 @@ function way_function (way)
local cursor = assert( sql_con:execute(sql_query) ) -- execute querty local cursor = assert( sql_con:execute(sql_query) ) -- execute querty
local row = cursor:fetch( {}, "a" ) -- fetch first (and only) row local row = cursor:fetch( {}, "a" ) -- fetch first (and only) row
way.speed = 20.0 -- default speed way.forward_speed = 20.0 -- default speed
if row then if row then
local val = tonumber(row.val) -- read 'val' from row local val = tonumber(row.val) -- read 'val' from row
if val > 10 then if val > 10 then
way.speed = way.speed / math.log10( val ) -- reduce speed by amount of industry close by way.forward_speed = way.forward_speed / math.log10( val ) -- reduce speed by amount of industry close by
end end
end end
cursor:close() -- done with this query cursor:close() -- done with this query

View File

@ -63,6 +63,10 @@ traffic_signal_penalty = 2
u_turn_penalty = 2 u_turn_penalty = 2
use_turn_restrictions = false use_turn_restrictions = false
--modes
local mode_normal = 1
local mode_ferry = 2
function get_exceptions(vector) function get_exceptions(vector)
for i,v in ipairs(restriction_exception_tags) do for i,v in ipairs(restriction_exception_tags) do
vector:Add(v) vector:Add(v)
@ -98,32 +102,32 @@ function node_function (node)
end end
function way_function (way) function way_function (way)
-- initial routability check, filters out buildings, boundaries, etc -- initial routability check, filters out buildings, boundaries, etc
local highway = way.tags:Find("highway") local highway = way.tags:Find("highway")
local route = way.tags:Find("route") local route = way.tags:Find("route")
local man_made = way.tags:Find("man_made") local man_made = way.tags:Find("man_made")
local railway = way.tags:Find("railway") local railway = way.tags:Find("railway")
local amenity = way.tags:Find("amenity") local amenity = way.tags:Find("amenity")
local public_transport = way.tags:Find("public_transport") local public_transport = way.tags:Find("public_transport")
if (not highway or highway == '') and if (not highway or highway == '') and
(not route or route == '') and (not route or route == '') and
(not railway or railway=='') and (not railway or railway=='') and
(not amenity or amenity=='') and (not amenity or amenity=='') and
(not man_made or man_made=='') and (not man_made or man_made=='') and
(not public_transport or public_transport=='') (not public_transport or public_transport=='')
then then
return 0 return
end end
-- don't route on ways that are still under construction -- don't route on ways that are still under construction
if highway=='construction' then if highway=='construction' then
return 0 return
end end
-- access -- access
local access = Access.find_access_tag(way, access_tags_hierachy) local access = Access.find_access_tag(way, access_tags_hierachy)
if access_tag_blacklist[access] then if access_tag_blacklist[access] then
return 0 return
end end
local name = way.tags:Find("name") local name = way.tags:Find("name")
@ -156,50 +160,52 @@ function way_function (way)
-- 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)
way.direction = Way.bidirectional
way.ignore_in_grid = true way.ignore_in_grid = true
if durationIsValid(duration) then if durationIsValid(duration) then
way.duration = math.max( 1, parseDuration(duration) ) way.duration = math.max( 1, parseDuration(duration) )
else else
way.speed = route_speeds[route] way.forward_speed = route_speeds[route]
way.backward_speed = route_speeds[route]
end end
way.forward_mode = mode_ferry
way.backward_mode = mode_ferry
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.forward_speed = platform_speeds[railway]
way.backward_speed = platform_speeds[railway]
elseif platform_speeds[public_transport] then elseif platform_speeds[public_transport] then
-- public_transport platforms (new tagging platform) -- public_transport platforms (new tagging platform)
way.speed = platform_speeds[public_transport] way.forward_speed = platform_speeds[public_transport]
way.backward_speed = platform_speeds[public_transport]
elseif amenity and amenity_speeds[amenity] then elseif amenity and amenity_speeds[amenity] then
-- parking areas -- parking areas
way.speed = amenity_speeds[amenity] way.forward_speed = amenity_speeds[amenity]
way.backward_speed = amenity_speeds[amenity]
elseif speeds[highway] then elseif speeds[highway] then
-- regular ways -- regular ways
way.speed = speeds[highway] way.forward_speed = speeds[highway]
way.backward_speed = speeds[highway]
elseif access and access_tag_whitelist[access] then elseif access and access_tag_whitelist[access] then
-- unknown way, but valid access tag -- unknown way, but valid access tag
way.speed = walking_speed way.forward_speed = walking_speed
way.backward_speed = walking_speed
end end
-- oneway -- oneway
if onewayClass == "yes" or onewayClass == "1" or onewayClass == "true" then if onewayClass == "yes" or onewayClass == "1" or onewayClass == "true" then
way.direction = Way.oneway way.backward_mode = 0
elseif onewayClass == "no" or onewayClass == "0" or onewayClass == "false" then elseif onewayClass == "no" or onewayClass == "0" or onewayClass == "false" then
way.direction = Way.bidirectional -- nothing to do
elseif onewayClass == "-1" then elseif onewayClass == "-1" then
way.direction = Way.opposite way.forward_mode = 0
else
way.direction = Way.bidirectional
end end
-- surfaces -- surfaces
if surface then if surface then
surface_speed = surface_speeds[surface] surface_speed = surface_speeds[surface]
if surface_speed then if surface_speed then
way.speed = math.min(way.speed, surface_speed) way.forward_speed = math.min(way.forward_speed, surface_speed)
way.backward_speed = math.min(way.backward_speed, surface_speed) way.backward_speed = math.min(way.backward_speed, surface_speed)
end end
end end
way.type = 1
return 1
end end

17
profiles/lib/maxspeed.lua Normal file
View File

@ -0,0 +1,17 @@
local math = math
module "MaxSpeed"
function limit(way,max,maxf,maxb)
if maxf and maxf>0 then
way.forward_speed = math.min(way.forward_speed, maxf)
elseif max and max>0 then
way.forward_speed = math.min(way.forward_speed, max)
end
if maxb and maxb>0 then
way.backward_speed = math.min(way.backward_speed, maxb)
elseif max and max>0 then
way.backward_speed = math.min(way.backward_speed, max)
end
end

View File

@ -6,10 +6,19 @@
-- 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
-- 5: steps down
-- 6: steps up
speed_profile = { speed_profile = {
["primary"] = 36, ["primary"] = 36,
["secondary"] = 18, ["secondary"] = 18,
["tertiary"] = 12, ["tertiary"] = 12,
["steps"] = 6,
["default"] = 24 ["default"] = 24
} }
@ -61,14 +70,21 @@ function way_function (way)
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
if highway == "river" then if highway == "river" then
local temp_speed = speed_forw; local temp_speed = speed_forw;
way.forward_mode = 3
way.backward_mode = 4
speed_forw = temp_speed*1.5 speed_forw = temp_speed*1.5
speed_back = temp_speed/1.5 speed_back = temp_speed/1.5
elseif highway == "steps" then
way.forward_mode = 5
way.backward_mode = 6
end end
if maxspeed_forward ~= nil and maxspeed_forward > 0 then if maxspeed_forward ~= nil and maxspeed_forward > 0 then
@ -87,26 +103,19 @@ function way_function (way)
end end
end end
way.speed = speed_forw way.forward_speed = speed_forw
if speed_back ~= way_forw then way.backward_speed = speed_back
way.backward_speed = speed_back
end
end end
if oneway == "no" or oneway == "0" or oneway == "false" then if oneway == "no" or oneway == "0" or oneway == "false" then
way.direction = Way.bidirectional -- nothing to do
elseif oneway == "-1" then elseif oneway == "-1" then
way.direction = Way.opposite way.forward_mode = 0
elseif oneway == "yes" or oneway == "1" or oneway == "true" or junction == "roundabout" then elseif oneway == "yes" or oneway == "1" or oneway == "true" or junction == "roundabout" then
way.direction = Way.oneway way.backward_mode = 0
else
way.direction = Way.bidirectional
end end
if junction == 'roundabout' then if junction == 'roundabout' then
way.roundabout = true way.roundabout = true
end end
way.type = 1
return 1
end end