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],
m_geometry_compressor.GetPositionForID(e1),
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;
BOOST_ASSERT(m_edge_based_node_list.back().IsCompressed());
@ -231,7 +233,9 @@ EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u, const NodeID nod
0,
SPECIAL_EDGEID,
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());
}
}
@ -500,7 +504,6 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedNodes()
}
BOOST_ASSERT(u < v);
BOOST_ASSERT(edge_data.type != SHRT_MAX);
// Note: edges that end on barrier nodes or on a turn restriction
// 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_data1.nameID,
turn_instruction,
edge_is_compressed);
edge_is_compressed,
edge_data2.travel_mode);
++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 &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
if (data1.roundabout && data2.roundabout)
{

View File

@ -1,6 +1,7 @@
#ifndef EDGE_BASED_NODE_H
#define EDGE_BASED_NODE_H
#include "../DataStructures/TravelMode.h"
#include "../Util/SimpleLogger.h"
#include "../typedefs.h"
@ -25,7 +26,9 @@ struct EdgeBasedNode
reverse_offset(0),
packed_geometry_id(SPECIAL_EDGEID),
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(
@ -40,7 +43,9 @@ struct EdgeBasedNode
int reverse_offset,
unsigned packed_geometry_id,
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),
reverse_edge_based_node_id(reverse_edge_based_node_id),
@ -53,7 +58,9 @@ struct EdgeBasedNode
reverse_offset(reverse_offset),
packed_geometry_id(packed_geometry_id),
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) ||
(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 short fwd_segment_position; // segment id in a compressed geometry
bool is_in_tiny_cc;
TravelMode forward_travel_mode : 4;
TravelMode backward_travel_mode : 4;
};
#endif //EDGE_BASED_NODE_H

View File

@ -52,17 +52,15 @@ NodeBasedEdge::NodeBasedEdge(NodeID source,
EdgeWeight weight,
bool forward,
bool backward,
short type,
bool roundabout,
bool in_tiny_cc,
bool access_restricted,
bool contra_flow,
TravelMode travel_mode,
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),
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

View File

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

View File

@ -13,23 +13,22 @@ struct NodeBasedEdgeData
{
NodeBasedEdgeData()
: 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),
roundabout(false), ignore_in_grid(false), contraFlow(false)
roundabout(false), ignore_in_grid(false), travel_mode(TRAVEL_MODE_INACCESSIBLE)
{
}
int distance;
unsigned edgeBasedNodeID;
unsigned nameID;
short type;
bool isAccessRestricted : 1;
bool shortcut : 1;
bool forward : 1;
bool backward : 1;
bool roundabout : 1;
bool ignore_in_grid : 1;
bool contraFlow : 1;
TravelMode travel_mode : 4;
void SwapDirectionFlags()
{
@ -42,7 +41,7 @@ struct NodeBasedEdgeData
{
return (forward == other.forward) && (backward == other.backward) &&
(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.ignore_in_grid = import_edge.in_tiny_cc;
edge.data.nameID = import_edge.name_id;
edge.data.type = import_edge.type;
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);
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
#include "TurnInstructions.h"
#include "../DataStructures/TravelMode.h"
#include "../typedefs.h"
#include <limits>
@ -38,16 +39,18 @@ struct OriginalEdgeData
explicit OriginalEdgeData(NodeID via_node,
unsigned name_id,
TurnInstruction turn_instruction,
bool compressed_geometry)
bool compressed_geometry,
TravelMode travel_mode)
: 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()
: via_node(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;
TurnInstruction turn_instruction;
bool compressed_geometry;
TravelMode travel_mode;
};
#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
#include <osrm/Coordinate.h>
#include "../DataStructures/TravelMode.h"
#include "../Util/SimpleLogger.h"
#include "../typedefs.h"
@ -39,7 +40,8 @@ struct PhantomNode
PhantomNode(NodeID forward_node_id, NodeID reverse_node_id, unsigned name_id,
int forward_weight, int reverse_weight, int forward_offset, int reverse_offset,
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),
reverse_node_id(reverse_node_id),
name_id(name_id),
@ -49,7 +51,9 @@ struct PhantomNode
reverse_offset(reverse_offset),
packed_geometry_id(packed_geometry_id),
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() :
@ -61,7 +65,9 @@ struct PhantomNode
forward_offset(0),
reverse_offset(0),
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;
@ -74,6 +80,8 @@ struct PhantomNode
unsigned packed_geometry_id;
FixedPointCoordinate location;
unsigned short fwd_segment_position;
TravelMode forward_travel_mode : 4;
TravelMode backward_travel_mode : 4;
int GetForwardWeightPlusOffset() const
{

View File

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

View File

@ -30,6 +30,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "TurnInstructions.h"
#include "../DataStructures/TravelMode.h"
#include "../typedefs.h"
#include <osrm/Coordinate.h>
@ -43,8 +44,9 @@ struct SegmentInformation
float length;
short bearing; // more than enough [0..3600] fits into 12 bits
TurnInstruction turn_instruction;
bool necessary:1;
bool is_via_location:1;
TravelMode travel_mode;
bool necessary;
bool is_via_location;
explicit SegmentInformation(const FixedPointCoordinate &location,
const NodeID name_id,
@ -52,9 +54,11 @@ struct SegmentInformation
const float length,
const TurnInstruction turn_instruction,
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),
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 EdgeWeight duration,
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),
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.packed_geometry_id,
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.
FixUpRoundingIssue(input_coordinate, result_phantom_node_vector.back());
@ -1077,7 +1079,9 @@ class StaticRTree
current_edge.reverse_offset,
current_edge.packed_geometry_id,
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;
}
}

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;
const EdgeWeight segment_duration =
(traversed_in_reverse ? source.reverse_weight : source.forward_weight);
AppendSegment(source.location,
PathData(0, source.name_id, TurnInstruction::HeadOn, segment_duration));
const TravelMode travel_mode =
(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);
}
@ -57,6 +60,8 @@ void DescriptionFactory::SetEndSegment(const PhantomNode &target,
target_phantom = target;
const EdgeWeight segment_duration =
(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,
target.name_id,
segment_duration,
@ -64,24 +69,44 @@ void DescriptionFactory::SetEndSegment(const PhantomNode &target,
is_via_location ? TurnInstruction::ReachViaLocation
: TurnInstruction::NoTurn,
true,
true);
true,
travel_mode);
BOOST_ASSERT(path_description.back().duration == segment_duration);
}
void DescriptionFactory::AppendSegment(const FixedPointCoordinate &coordinate,
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;
}
// 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_point.name_id,
path_point.segment_duration,
0.f,
path_point.turn_instruction);
turn,
path_point.travel_mode);
}
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(
static_cast<unsigned>(round(bearing_value)));
json_instruction_row.values.push_back(segment.travel_mode);
route_segments_list.emplace_back(
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())
{
BOOST_ASSERT(edge_iterator->speed != -1);
BOOST_ASSERT(edge_iterator->type >= 0);
edge_iterator->target_coordinate.lat = node_iterator->lat;
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 *)&edge_iterator->type, sizeof(short));
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_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_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));
++number_of_used_edges;
}

View File

@ -29,6 +29,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define EXTRACTION_WAY_H
#include "../DataStructures/HashTable.h"
#include "../DataStructures/TravelMode.h"
#include "../typedefs.h"
#include <string>
@ -44,15 +45,15 @@ struct ExtractionWay
nameID = INVALID_NAMEID;
path.clear();
keyVals.Clear();
direction = ExtractionWay::notSure;
speed = -1;
forward_speed = -1;
backward_speed = -1;
duration = -1;
type = -1;
access = true;
roundabout = false;
isAccessRestricted = false;
ignoreInGrid = false;
forward_travel_mode = TRAVEL_MODE_DEFAULT;
backward_travel_mode = TRAVEL_MODE_DEFAULT;
}
enum Directions
@ -60,20 +61,70 @@ struct ExtractionWay
oneway,
bidirectional,
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 nameID;
double speed;
double forward_speed;
double backward_speed;
double duration;
Directions direction;
std::string name;
short type;
bool access;
bool roundabout;
bool isAccessRestricted;
bool ignoreInGrid;
std::vector<NodeID> path;
HashTable<std::string, std::string> keyVals;
TravelMode forward_travel_mode : 4;
TravelMode backward_travel_mode : 4;
};
#endif // EXTRACTION_WAY_H

View File

@ -63,7 +63,11 @@ bool ExtractorCallbacks::ProcessRestriction(const InputRestrictionContainer &res
/** warning: caller needs to take care of synchronization! */
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
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
// 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;
return;
@ -106,29 +110,34 @@ void ExtractorCallbacks::ProcessWay(ExtractionWay &parsed_way)
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());
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 =
(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)
{
external_memory.all_edges_list.push_back(InternalExtractorEdge(
parsed_way.path[n],
parsed_way.path[n + 1],
parsed_way.type,
(split_edge ? ExtractionWay::oneway : parsed_way.direction),
parsed_way.speed,
((split_edge || TRAVEL_MODE_INACCESSIBLE == parsed_way.backward_travel_mode) ? ExtractionWay::oneway
: ExtractionWay::bidirectional),
parsed_way.forward_speed,
parsed_way.nameID,
parsed_way.roundabout,
parsed_way.ignoreInGrid,
(0 < parsed_way.duration),
parsed_way.isAccessRestricted,
false,
parsed_way.forward_travel_mode,
split_edge));
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)
{ // 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());
for (std::vector<NodeID>::size_type n = 0; n < parsed_way.path.size() - 1; ++n)
{
external_memory.all_edges_list.push_back(
InternalExtractorEdge(parsed_way.path[n],
parsed_way.path[n + 1],
parsed_way.type,
ExtractionWay::oneway,
parsed_way.backward_speed,
parsed_way.nameID,
@ -158,7 +167,7 @@ void ExtractorCallbacks::ProcessWay(ExtractionWay &parsed_way)
parsed_way.ignoreInGrid,
(0 < parsed_way.duration),
parsed_way.isAccessRestricted,
(ExtractionWay::oneway == parsed_way.direction),
parsed_way.backward_travel_mode,
split_edge));
}
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
#include "../typedefs.h"
#include "../DataStructures/TravelMode.h"
#include <osrm/Coordinate.h>
#include <boost/assert.hpp>
@ -36,15 +37,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
struct 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_contra_flow(false), is_split(false)
travel_mode(TRAVEL_MODE_INACCESSIBLE), is_split(false)
{
}
explicit InternalExtractorEdge(NodeID start,
NodeID target,
short type,
short direction,
double speed,
unsigned name_id,
@ -52,30 +52,28 @@ struct InternalExtractorEdge
bool is_in_tiny_cc,
bool is_duration_set,
bool is_access_restricted,
bool is_contra_flow,
TravelMode travel_mode,
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),
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
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()
{
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 target;
short type;
short direction;
double speed;
unsigned name_id;
@ -83,7 +81,7 @@ struct InternalExtractorEdge
bool is_in_tiny_cc;
bool is_duration_set;
bool is_access_restricted;
bool is_contra_flow;
TravelMode travel_mode : 4;
bool is_split;
FixedPointCoordinate source_coordinate;

View File

@ -76,16 +76,17 @@ void ScriptingEnvironment::initLuaState(lua_State* lua_state)
// .def(luabind::constructor<>())
.def_readonly("id", &ExtractionWay::id)
.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("duration", &ExtractionWay::duration)
.def_readwrite("type", &ExtractionWay::type)
.def_readwrite("access", &ExtractionWay::access)
.def_readwrite("roundabout", &ExtractionWay::roundabout)
.def_readwrite("is_access_restricted", &ExtractionWay::isAccessRestricted)
.def_readwrite("ignore_in_grid", &ExtractionWay::ignoreInGrid)
.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")[
luabind::value("notSure", 0),
luabind::value("oneway", 1),

View File

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

View File

@ -227,6 +227,8 @@ template <class DataFacadeT> class BasicRoutingInterface
BOOST_ASSERT_MSG(!ed.shortcut, "original edge flagged as shortcut");
unsigned name_index = facade->GetNameIndexFromEdgeID(ed.id);
const TurnInstruction turn_instruction = facade->GetTurnInstructionForEdgeID(ed.id);
const TravelMode travel_mode = facade->GetTravelModeForEdgeID(ed.id);
if (!facade->EdgeIsCompressed(ed.id))
{
@ -234,7 +236,8 @@ template <class DataFacadeT> class BasicRoutingInterface
unpacked_path.emplace_back(facade->GetGeometryIndexForEdgeID(ed.id),
name_index,
turn_instruction,
ed.distance);
ed.distance,
travel_mode);
}
else
{
@ -255,7 +258,7 @@ template <class DataFacadeT> class BasicRoutingInterface
BOOST_ASSERT(start_index <= end_index);
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().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))
{
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],
phantom_node_pair.target_phantom.name_id,
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 TravelMode GetTravelModeForEdgeID(const unsigned id) const = 0;
virtual bool LocateClosestEndPointForCoordinate(const FixedPointCoordinate &input_coordinate,
FixedPointCoordinate &result,
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<unsigned, false>::vector m_name_ID_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<bool, false>::vector m_egde_is_compressed;
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_name_ID_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);
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_name_ID_list[i] = current_edge_data.name_id;
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;
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);
}
TravelMode GetTravelModeForEdgeID(const unsigned id) const
{
return m_travel_mode_list.at(id);
}
bool LocateClosestEndPointForCoordinate(const FixedPointCoordinate &input_coordinate,
FixedPointCoordinate &result,
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<unsigned, true>::vector m_name_ID_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<unsigned, true>::vector m_name_begin_indices;
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);
}
TravelMode GetTravelModeForEdgeID(const unsigned id) const
{
return m_travel_mode_list.at(id);
}
bool LocateClosestEndPointForCoordinate(const FixedPointCoordinate &input_coordinate,
FixedPointCoordinate &result,
const unsigned zoom_level = 18) final

View File

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

View File

@ -126,11 +126,10 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &input_stream,
edge_list.reserve(m);
EdgeWeight weight;
short type;
NodeID nameID;
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)
{
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 *)&dir, sizeof(short));
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 *)&is_roundabout, 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_contra_flow, sizeof(bool));
input_stream.read((char *)&travel_mode, sizeof(TravelMode));
input_stream.read((char *)&is_split, sizeof(bool));
BOOST_ASSERT_MSG(length > 0, "loaded null length edge");
@ -161,8 +159,6 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &input_stream,
forward = false;
}
BOOST_ASSERT(type >= 0);
// translate the external NodeIDs to internal IDs
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())
@ -196,11 +192,10 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &input_stream,
weight,
forward,
backward,
type,
is_roundabout,
ignore_in_grid,
is_access_restricted,
is_contra_flow,
travel_mode,
is_split);
}
@ -303,10 +298,10 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &input_stream,
edge_list.reserve(m);
EdgeWeight weight;
short type;
NodeID nameID;
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)
{
@ -315,20 +310,17 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &input_stream,
input_stream.read((char *)&length, sizeof(int));
input_stream.read((char *)&dir, sizeof(short));
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 *)&is_roundabout, 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_contra_flow, sizeof(bool));
input_stream.read((char *)&travel_mode, sizeof(TravelMode));
input_stream.read((char *)&is_split, sizeof(bool));
BOOST_ASSERT_MSG(length > 0, "loaded null length edge");
BOOST_ASSERT_MSG(weight > 0, "loaded null weight");
BOOST_ASSERT_MSG(0 <= dir && dir <= 2, "loaded bogus direction");
BOOST_ASSERT(type >= 0);
// translate the external NodeIDs to internal IDs
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())

View File

@ -1,10 +1,15 @@
@routing @bicycle @mode
Feature: Bike - Mode flag
# bicycle modes:
# 1 bike
# 2 pushing
# 3 ferry
# 4 train
Background:
Given the profile "bicycle"
@todo
Scenario: Bike - Mode when using a ferry
Given the node map
| a | b | |
@ -18,14 +23,33 @@ Feature: Bike - Mode flag
When I route I should get
| from | to | route | turns | modes |
| a | d | ab,bc,cd | head,right,left, destination | bike,ferry,bike |
| d | a | cd,bc,ab | head,right,left, destination | bike,ferry,bike |
| c | a | bc,ab | head,left,destination | ferry,bike |
| d | b | cd,bc | head,right,destination | bike,ferry |
| a | c | ab,bc | head,right,destination | bike,ferry |
| b | d | bc,cd | head,left,destination | ferry,bike |
| 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 |
@todo
Scenario: Bike - Mode when pushing bike against oneways
Given the node map
| a | b | |
@ -39,14 +63,13 @@ Feature: Bike - Mode flag
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 |
| 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 |
@todo
Scenario: Bike - Mode when pushing on pedestrain streets
Given the node map
| a | b | |
@ -60,14 +83,13 @@ Feature: Bike - Mode flag
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 |
| a | d | ab,bc,cd | head,right,left,destination | 1,2,1 |
| d | a | cd,bc,ab | head,right,left,destination | 1,2,1 |
| c | a | bc,ab | head,left,destination | 2,1 |
| d | b | cd,bc | head,right,destination | 1,2 |
| a | c | ab,bc | head,right,destination | 1,2 |
| b | d | bc,cd | head,left,destination | 2,1 |
@todo
Scenario: Bike - Mode when pushing on pedestrain areas
Given the node map
| a | b | | |
@ -81,9 +103,75 @@ Feature: Bike - Mode flag
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 |
| 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
| a | b |
And the ways
| nodes | oneway |
| ab | yes |
When I route I should get
| from | to | route | modes |
| a | b | ab | 1 |
| b | a | ab | 2 |
Scenario: Bicycle - Modes when starting on reverse oneway
Given the node map
| a | b |
And the ways
| nodes | oneway |
| ab | -1 |
When I route I should get
| from | to | route | modes |
| a | b | ab | 2 |
| b | a | ab | 1 |

View File

@ -5,8 +5,8 @@ Feature: Bike - Accessability of different way types
Given the profile "bicycle"
Given the shortcuts
| key | value |
| bike | 49s ~20% |
| foot | 121s ~20% |
| bike | 15 km/h ~20% |
| foot | 5 km/h ~20% |
Scenario: Bike - Pushing bikes on pedestrian-only ways
Then routability should be
@ -100,9 +100,9 @@ Feature: Bike - Accessability of different way types
When I route I should get
| from | to | route | turns |
| a | d | ab,bc,cd | head,right,left,destination |
| d | a | cd,bc,ab | head,enter_contraflow,leave_contraflow,destination |
| c | a | bc,ab | head,leave_contraflow,destination |
| d | b | cd,bc | head,enter_contraflow,destination |
| d | a | cd,bc,ab | head,right,left,destination |
| c | a | bc,ab | head,left,destination |
| d | b | cd,bc | head,right,destination |
@todo
Scenario: Bike - Instructions when pushing bike on footway/pedestrian, etc.
@ -119,6 +119,6 @@ Feature: Bike - Accessability of different way types
When I route I should get
| from | to | route | turns |
| a | d | ab,bc,cd | head,right,left,destination |
| d | a | cd,bc,ab | head,enter_contraflow,leave_contraflow,destination |
| c | a | bc,ab | head,leave_contraflow,destination |
| d | b | cd,bc | head,enter_contraflow,destination |
| d | a | cd,bc,ab | head,right,left,destination |
| c | a | bc,ab | head,left,destination |
| d | b | cd,bc | head,right,destination |

View File

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

View File

@ -41,10 +41,10 @@ OSRM will use 4/5 of the projected free-flow speed.
| highway | maxspeed | maxspeed:forward | maxspeed:backward | forw | backw |
| primary | | | | 51 km/h | 51 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 | 15 | 60 | | 48 km/h | 15 km/h +- 1 |
| primary | 15 | | 60 | 12 km/h +- 1| 48 km/h |
| primary | 15 | 60 | | 48 km/h | 12 km/h |
| primary | 15 | | 60 | 12 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

View File

@ -17,15 +17,15 @@ Feature: Foot - Handle ferry routes
| efg | primary | | |
When I route I should get
| from | to | route |
| a | g | abc,cde,efg |
| b | f | abc,cde,efg |
| e | c | cde |
| e | b | cde,abc |
| e | a | cde,abc |
| c | e | cde |
| c | f | cde,efg |
| c | g | cde,efg |
| from | to | route | modes |
| a | g | abc,cde,efg | 1,2,1 |
| b | f | abc,cde,efg | 1,2,1 |
| e | c | cde | 2 |
| e | b | cde,abc | 2,1 |
| e | a | cde,abc | 2,1 |
| c | e | cde | 2 |
| c | f | cde,efg | 2,1 |
| c | g | cde,efg | 2,1 |
Scenario: Foot - Ferry duration, single node
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
case want
when '', 'x'
output_row[direction] = result[direction][:status].to_s
output_row[direction] = result[direction][:status] ? result[direction][:status].to_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/
output_row[direction] = "#{result[direction][:speed]} km/h"
output_row[direction] = result[direction][:speed] ? "#{result[direction][:speed]} km/h" : ''
else
raise "*** Unknown expectation format: #{want}"
end

View File

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

View File

@ -1,26 +1,227 @@
@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:
Given the profile "testbot"
@todo
Scenario: Bike - Mode
Scenario: Testbot - Modes in each direction, different forward/backward speeds
Given the node map
| a | b | |
| | c | d |
| | 0 | 1 | |
| a | | | b |
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 |
| ab | primary | | |
| bc | | ferry | 0:01 |
| cd | primary | | |
| de | primary | | |
| ef | primary | | |
When I route I should get
| from | to | route | turns | modes |
| a | d | ab,bc,cd | head,right,left,destination | bot,ferry,bot |
| d | a | cd,bc,ab | head,right left,destination | bot,ferry,bot |
| c | a | bc,ab | head,left,destination | ferry,bot |
| d | b | cd,bc | head,right,destination | bot,ferry |
| a | c | ab,bc | head,right,destination | bot,ferry |
| b | d | bc,cd | head,left,destination | ferry,bot |
| 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
| from | to | route | modes |
| a | g | abc,cde,efg | 1,3,1 |
| b | f | abc,cde,efg | 1,3,1 |
| e | c | cde | 4 |
| e | b | cde,abc | 4,1 |
| e | a | cde,abc | 4,1 |
| 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 |
| h | g | ha,ab,bc,cd,de,ef,fg |
| 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/maxspeed")
-- 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 }
@ -94,7 +95,13 @@ u_turn_penalty = 20
use_turn_restrictions = false
turn_penalty = 60
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)
@ -161,18 +168,18 @@ function way_function (way)
(not man_made or man_made=='') and
(not public_transport or public_transport=='')
then
return 0
return
end
-- don't route on ways or railways that are still under construction
if highway=='construction' or railway=='construction' then
return 0
return
end
-- access
local access = Access.find_access_tag(way, access_tags_hierachy)
if access_tag_blacklist[access] then
return 0
return
end
-- other tags
@ -193,6 +200,7 @@ function way_function (way)
local area = way.tags:Find("area")
local foot = way.tags:Find("foot")
local surface = way.tags:Find("surface")
local bicycle = way.tags:Find("bicycle")
-- name
if "" ~= ref and "" ~= name then
@ -215,126 +223,152 @@ function way_function (way)
-- speed
if route_speeds[route] then
-- 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
if durationIsValid(duration) then
way.duration = math.max( 1, parseDuration(duration) )
else
way.speed = route_speeds[route]
way.forward_speed = route_speeds[route]
way.backward_speed = route_speeds[route]
end
elseif railway and platform_speeds[railway] then
-- 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
-- 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
way.forward_mode = mode_train
way.backward_mode = mode_train
-- railways
if access and access_tag_whitelist[access] then
way.speed = railway_speeds[railway]
way.direction = Way.bidirectional
way.forward_speed = railway_speeds[railway]
way.backward_speed = railway_speeds[railway]
end
elseif amenity and amenity_speeds[amenity] then
-- parking areas
way.speed = amenity_speeds[amenity]
way.forward_speed = amenity_speeds[amenity]
way.backward_speed = amenity_speeds[amenity]
elseif bicycle_speeds[highway] then
-- 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
-- unknown way, but valid access tag
way.speed = default_speed
way.forward_speed = default_speed
way.backward_speed = default_speed
else
-- biking not allowed, maybe we can push our bike?
-- essentially requires pedestrian profiling, for example foot=no mean we can't push a bike
-- TODO: if we can push, the way should be marked as pedestrion mode, but there's no way to do it yet from lua..
if foot ~= 'no' then
if foot ~= 'no' and junction ~= "roundabout" then
if pedestrian_speeds[highway] then
-- 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
-- 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
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
-- direction
way.direction = Way.bidirectional
local impliedOneway = false
if junction == "roundabout" or highway == "motorway_link" or highway == "motorway" then
way.direction = Way.oneway
impliedOneway = true
end
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
way.direction = Way.bidirectional
-- prevent implied oneway
elseif onewayClass == "-1" then
way.direction = Way.opposite
way.forward_mode = 0
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
if impliedOneway then
way.direction = Way.opposite
else
way.direction = Way.bidirectional
way.forward_mode = 0
way.backward_mode = mode_normal
way.backward_speed = bicycle_speeds["cycleway"]
end
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
if impliedOneway then
way.direction = Way.opposite
else
way.direction = Way.bidirectional
way.forward_mode = 0
way.backward_mode = mode_normal
way.backward_speed = bicycle_speeds["cycleway"]
end
elseif cycleway_right and cycleway_tags[cycleway_right] then
if impliedOneway then
way.direction = Way.oneway
else
way.direction = Way.bidirectional
way.forward_mode = mode_normal
way.backward_speed = bicycle_speeds["cycleway"]
way.backward_mode = 0
end
elseif oneway == "-1" then
way.direction = Way.opposite
elseif oneway == "yes" or oneway == "1" or oneway == "true" then
way.direction = Way.oneway
way.forward_mode = 0
elseif oneway == "yes" or oneway == "1" or oneway == "true" or impliedOneway then
way.backward_mode = 0
end
-- pushing bikes
if bicycle_speeds[highway] or pedestrian_speeds[highway] then
if foot ~= 'no' then
if junction ~= "roundabout" then
if way.direction == Way.oneway then
if foot ~= "no" and junction ~= "roundabout" then
if way.backward_mode == 0 then
way.backward_speed = walking_speed
elseif way.direction == Way.opposite then
way.backward_speed = walking_speed
way.speed = way.speed
way.backward_mode = mode_pushing
elseif way.forward_mode == 0 then
way.forward_speed = walking_speed
way.forward_mode = mode_pushing
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
-- cycleways
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
way.speed = bicycle_speeds["cycleway"]
way.forward_speed = bicycle_speeds["cycleway"]
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
-- surfaces
if surface then
surface_speed = surface_speeds[surface]
if surface_speed then
if way.speed > 0 then
way.speed = surface_speed
if way.forward_speed > 0 then
way.forward_speed = surface_speed
end
if way.backward_speed > 0 then
way.backward_speed = surface_speed
@ -343,26 +377,7 @@ function way_function (way)
end
-- maxspeed
-- TODO: maxspeed of backward direction
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
MaxSpeed.limit( way, maxspeed, maxspeed_forward, maxspeed_backward )
end
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
--modes
local mode_normal = 1
local mode_ferry = 2
local function find_access_tag(source,access_tags_hierachy)
for i,v in ipairs(access_tags_hierachy) do
local has_tag = source.tags:Holds(v)
@ -169,8 +174,10 @@ function way_function (way)
if durationIsValid(duration) then
way.duration = max( parseDuration(duration), 1 );
end
way.direction = Way.bidirectional
way.speed = route_speed
way.forward_mode = mode_ferry
way.backward_mode = mode_ferry
way.forward_speed = route_speed
way.backward_speed = route_speed
end
-- leave early of this way is not accessible
@ -178,30 +185,34 @@ function way_function (way)
return
end
if way.speed == -1 then
if way.forward_speed == -1 then
local highway_speed = speed_profile[highway]
local max_speed = parse_maxspeed( way.tags:Find("maxspeed") )
-- Set the avg speed on the way if it is accessible by road class
if 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
else
way.speed = highway_speed
way.forward_speed = highway_speed
way.backward_speed = highway_speed
end
else
-- Set the avg speed on ways that are marked accessible
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
if 0 == max_speed then
max_speed = math.huge
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
if -1 == way.speed then
if -1 == way.forward_speed and -1 == way.backward_speed then
return
end
@ -237,17 +248,16 @@ function way_function (way)
end
-- Set direction according to tags on way
way.direction = Way.bidirectional
if obey_oneway then
if oneway == "-1" then
way.direction = Way.opposite
way.forward_mode = 0
elseif oneway == "yes" or
oneway == "1" or
oneway == "true" or
junction == "roundabout" or
(highway == "motorway_link" and oneway ~="no") or
(highway == "motorway" and oneway ~= "no") then
way.direction = Way.oneway
way.backward_mode = 0
end
end
@ -255,10 +265,10 @@ function way_function (way)
local maxspeed_forward = parse_maxspeed(way.tags:Find( "maxspeed:forward"))
local maxspeed_backward = parse_maxspeed(way.tags:Find( "maxspeed:backward"))
if maxspeed_forward > 0 then
if Way.bidirectional == way.direction then
way.backward_speed = way.speed
if 0 ~= way.forward_mode and 0 ~= way.backward_mode then
way.backward_speed = way.forward_speed
end
way.speed = maxspeed_forward
way.forward_speed = maxspeed_forward
end
if maxspeed_backward > 0 then
way.backward_speed = maxspeed_backward
@ -268,14 +278,12 @@ function way_function (way)
if ignore_in_grid[highway] then
way.ignore_in_grid = true
end
way.type = 1
-- scale speeds to get better avg driving times
way.speed = way.speed * speed_reduction
if maxspeed_backward > 0 then
way.forward_speed = way.forward_speed * speed_reduction
if way.backward_speed > 0 then
way.backward_speed = way.backward_speed*speed_reduction
end
return
end
-- 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 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
local val = tonumber(row.val) -- read 'val' from row
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
cursor:close() -- done with this query

View File

@ -63,6 +63,10 @@ traffic_signal_penalty = 2
u_turn_penalty = 2
use_turn_restrictions = false
--modes
local mode_normal = 1
local mode_ferry = 2
function get_exceptions(vector)
for i,v in ipairs(restriction_exception_tags) do
vector:Add(v)
@ -112,18 +116,18 @@ function way_function (way)
(not man_made or man_made=='') and
(not public_transport or public_transport=='')
then
return 0
return
end
-- don't route on ways that are still under construction
if highway=='construction' then
return 0
return
end
-- access
local access = Access.find_access_tag(way, access_tags_hierachy)
if access_tag_blacklist[access] then
return 0
return
end
local name = way.tags:Find("name")
@ -156,50 +160,52 @@ function way_function (way)
-- speed
if route_speeds[route] then
-- ferries (doesn't cover routes tagged using relations)
way.direction = Way.bidirectional
way.ignore_in_grid = true
if durationIsValid(duration) then
way.duration = math.max( 1, parseDuration(duration) )
else
way.speed = route_speeds[route]
way.forward_speed = route_speeds[route]
way.backward_speed = route_speeds[route]
end
way.forward_mode = mode_ferry
way.backward_mode = mode_ferry
elseif railway and platform_speeds[railway] then
-- 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
-- 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
-- parking areas
way.speed = amenity_speeds[amenity]
way.forward_speed = amenity_speeds[amenity]
way.backward_speed = amenity_speeds[amenity]
elseif speeds[highway] then
-- regular ways
way.speed = speeds[highway]
way.forward_speed = speeds[highway]
way.backward_speed = speeds[highway]
elseif access and access_tag_whitelist[access] then
-- unknown way, but valid access tag
way.speed = walking_speed
way.forward_speed = walking_speed
way.backward_speed = walking_speed
end
-- oneway
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
way.direction = Way.bidirectional
-- nothing to do
elseif onewayClass == "-1" then
way.direction = Way.opposite
else
way.direction = Way.bidirectional
way.forward_mode = 0
end
-- surfaces
if surface then
surface_speed = surface_speeds[surface]
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)
end
end
way.type = 1
return 1
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
-- 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 = {
["primary"] = 36,
["secondary"] = 18,
["tertiary"] = 12,
["steps"] = 6,
["default"] = 24
}
@ -61,14 +70,21 @@ function way_function (way)
if route ~= nil and durationIsValid(duration) then
way.duration = math.max( 1, parseDuration(duration) )
way.forward_mode = 2
way.backward_mode = 2
else
local speed_forw = speed_profile[highway] or speed_profile['default']
local speed_back = speed_forw
if highway == "river" then
local temp_speed = speed_forw;
way.forward_mode = 3
way.backward_mode = 4
speed_forw = temp_speed*1.5
speed_back = temp_speed/1.5
elseif highway == "steps" then
way.forward_mode = 5
way.backward_mode = 6
end
if maxspeed_forward ~= nil and maxspeed_forward > 0 then
@ -87,26 +103,19 @@ function way_function (way)
end
end
way.speed = speed_forw
if speed_back ~= way_forw then
way.forward_speed = speed_forw
way.backward_speed = speed_back
end
end
if oneway == "no" or oneway == "0" or oneway == "false" then
way.direction = Way.bidirectional
-- nothing to do
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
way.direction = Way.oneway
else
way.direction = Way.bidirectional
way.backward_mode = 0
end
if junction == 'roundabout' then
way.roundabout = true
end
way.type = 1
return 1
end