Allow specifing a weight for routing that is independent of duration

This commit is contained in:
Patrick Niklaus
2016-05-12 18:50:10 +02:00
committed by Patrick Niklaus
parent e463733138
commit 279f8aabfb
85 changed files with 2100 additions and 853 deletions
@@ -19,8 +19,9 @@ class CompressedEdgeContainer
struct OnewayCompressedEdge
{
public:
NodeID node_id; // refers to an internal node-based-node
EdgeWeight weight; // the weight of the edge leading to this node
NodeID node_id; // refers to an internal node-based-node
EdgeWeight weight; // the weight of the edge leading to this node
EdgeWeight duration; // the duration of the edge leading to this node
};
using OnewayEdgeBucket = std::vector<OnewayCompressedEdge>;
@@ -31,10 +32,14 @@ class CompressedEdgeContainer
const NodeID via_node_id,
const NodeID target_node,
const EdgeWeight weight1,
const EdgeWeight weight2);
const EdgeWeight weight2,
const EdgeWeight duration1,
const EdgeWeight duration2);
void
AddUncompressedEdge(const EdgeID edge_id, const NodeID target_node, const EdgeWeight weight);
void AddUncompressedEdge(const EdgeID edge_id,
const NodeID target_node,
const EdgeWeight weight,
const EdgeWeight duration);
void InitializeBothwayVector();
unsigned ZipEdges(const unsigned f_edge_pos, const unsigned r_edge_pos);
@@ -62,6 +67,8 @@ class CompressedEdgeContainer
std::vector<NodeID> m_compressed_geometry_nodes;
std::vector<EdgeWeight> m_compressed_geometry_fwd_weights;
std::vector<EdgeWeight> m_compressed_geometry_rev_weights;
std::vector<EdgeWeight> m_compressed_geometry_fwd_durations;
std::vector<EdgeWeight> m_compressed_geometry_rev_durations;
std::vector<unsigned> m_free_list;
std::unordered_map<EdgeID, unsigned> m_edge_id_to_list_index_map;
std::unordered_map<EdgeID, unsigned> m_forward_edge_id_to_zipped_index_map;
+6 -2
View File
@@ -30,9 +30,13 @@ struct EdgeBasedEdge
NodeID target;
NodeID edge_id;
EdgeWeight weight : 30;
bool forward : 1;
bool backward : 1;
std::uint32_t forward : 1;
std::uint32_t backward : 1;
};
static_assert(sizeof(extractor::EdgeBasedEdge) == 16,
"Size of extractor::EdgeBasedEdge type is "
"bigger than expected. This will influence "
"memory consumption.");
// Impl.
+20 -6
View File
@@ -6,6 +6,7 @@
#include "extractor/compressed_edge_container.hpp"
#include "extractor/edge_based_edge.hpp"
#include "extractor/edge_based_node.hpp"
#include "extractor/extraction_turn.hpp"
#include "extractor/original_edge_data.hpp"
#include "extractor/profile_properties.hpp"
#include "extractor/query_node.hpp"
@@ -65,15 +66,25 @@ struct SegmentBlock
static_assert(sizeof(SegmentBlock) == 20, "SegmentBlock is not packed correctly");
#pragma pack(push, 1)
struct PenaltyBlock
struct TurnPenaltiesHeader
{
//! the number of penalties in each block
std::uint64_t number_of_penalties;
};
#pragma pack(pop)
static_assert(std::is_trivial<TurnPenaltiesHeader>::value, "TurnPenaltiesHeader is not trivial");
static_assert(sizeof(TurnPenaltiesHeader) == 8, "TurnPenaltiesHeader is not packed correctly");
#pragma pack(push, 1)
struct TurnIndexBlock
{
std::uint32_t fixed_penalty;
OSMNodeID from_id;
OSMNodeID via_id;
OSMNodeID to_id;
};
#pragma pack(pop)
static_assert(sizeof(PenaltyBlock) == 28, "PenaltyBlock is not packed correctly");
static_assert(std::is_trivial<TurnIndexBlock>::value, "TurnIndexBlock is not trivial");
static_assert(sizeof(TurnIndexBlock) == 24, "TurnIndexBlock is not packed correctly");
}
class EdgeBasedGraphFactory
@@ -98,7 +109,9 @@ class EdgeBasedGraphFactory
const std::string &original_edge_data_filename,
const std::string &turn_lane_data_filename,
const std::string &edge_segment_lookup_filename,
const std::string &edge_penalty_filename,
const std::string &turn_weight_penalties_filename,
const std::string &turn_duration_penalties_filename,
const std::string &turn_penalties_index_filename,
const bool generate_edge_lookup);
// The following get access functions destroy the content in the factory
@@ -157,14 +170,15 @@ class EdgeBasedGraphFactory
std::vector<guidance::TurnLaneType::Mask> &turn_lane_masks;
guidance::LaneDescriptionMap &lane_description_map;
void CompressGeometry();
unsigned RenumberEdges();
void GenerateEdgeExpandedNodes();
void GenerateEdgeExpandedEdges(ScriptingEnvironment &scripting_environment,
const std::string &original_edge_data_filename,
const std::string &turn_lane_data_filename,
const std::string &edge_segment_lookup_filename,
const std::string &edge_fixed_penalties_filename,
const std::string &turn_weight_penalties_filename,
const std::string &turn_duration_penalties_filename,
const std::string &turn_penalties_index_filename,
const bool generate_edge_lookup);
void InsertEdgeBasedNode(const NodeID u, const NodeID v);
+32
View File
@@ -0,0 +1,32 @@
#ifndef OSRM_EXTRACTION_SEGMENT_HPP
#define OSRM_EXTRACTION_SEGMENT_HPP
#include <util/coordinate.hpp>
namespace osrm
{
namespace extractor
{
struct ExtractionSegment
{
ExtractionSegment(const osrm::util::Coordinate source_,
const osrm::util::Coordinate target_,
double distance_,
double weight_,
double duration_)
: source(source_), target(target_), distance(distance_), weight(weight_),
duration(duration_)
{
}
const osrm::util::Coordinate source;
const osrm::util::Coordinate target;
const double distance;
double weight;
double duration;
};
}
}
#endif
+34
View File
@@ -0,0 +1,34 @@
#ifndef OSRM_EXTRACTION_TURN_HPP
#define OSRM_EXTRACTION_TURN_HPP
#include <boost/numeric/conversion/cast.hpp>
#include <extractor/guidance/intersection.hpp>
#include <cstdint>
namespace osrm
{
namespace extractor
{
struct ExtractionTurn
{
ExtractionTurn(const guidance::ConnectedRoad &turn, bool has_traffic_light)
: angle(180. - turn.angle), turn_type(turn.instruction.type),
direction_modifier(turn.instruction.direction_modifier),
has_traffic_light(has_traffic_light), weight(0.), duration(0.)
{
}
const double angle;
const guidance::TurnType::Enum turn_type;
const guidance::DirectionModifier::Enum direction_modifier;
const bool has_traffic_light;
double weight;
double duration;
};
}
}
#endif
+10
View File
@@ -42,7 +42,10 @@ struct ExtractionWay
{
forward_speed = -1;
backward_speed = -1;
forward_rate = -1;
backward_rate = -1;
duration = -1;
weight = -1;
roundabout = false;
circular = false;
is_startpoint = true;
@@ -84,9 +87,16 @@ struct ExtractionWay
}
const char *GetTurnLanesBackward() const { return turn_lanes_backward.c_str(); }
// speed in km/h
double forward_speed;
double backward_speed;
// weight per meter
double forward_rate;
double backward_rate;
// duration of the whole way in both directions
double duration;
// weight of the whole way in both directions
double weight;
std::string name;
std::string ref;
std::string pronunciation;
+4 -1
View File
@@ -43,6 +43,7 @@ class ExtractionContainers;
struct InputRestrictionContainer;
struct ExtractionNode;
struct ExtractionWay;
struct ProfileProperties;
/**
* This class is used by the extractor with the results of the
@@ -61,9 +62,11 @@ class ExtractorCallbacks
std::unordered_map<MapKey, MapVal> string_map;
guidance::LaneDescriptionMap lane_description_map;
ExtractionContainers &external_memory;
bool fallback_to_duration;
public:
explicit ExtractorCallbacks(ExtractionContainers &extraction_containers);
explicit ExtractorCallbacks(ExtractionContainers &extraction_containers,
const ProfileProperties &properties);
ExtractorCallbacks(const ExtractorCallbacks &) = delete;
ExtractorCallbacks &operator=(const ExtractorCallbacks &) = delete;
+6 -2
View File
@@ -71,7 +71,9 @@ struct ExtractorConfig
rtree_nodes_output_path = basepath + ".osrm.ramIndex";
rtree_leafs_output_path = basepath + ".osrm.fileIndex";
edge_segment_lookup_path = basepath + ".osrm.edge_segment_lookup";
edge_penalty_path = basepath + ".osrm.edge_penalties";
turn_duration_penalties_path = basepath + ".osrm.turn_duration_penalties";
turn_weight_penalties_path = basepath + ".osrm.turn_weight_penalties";
turn_penalties_index_path = basepath + ".osrm.turn_penalties_index";
edge_based_node_weights_output_path = basepath + ".osrm.enw";
profile_properties_output_path = basepath + ".osrm.properties";
intersection_class_data_output_path = basepath + ".osrm.icd";
@@ -95,12 +97,14 @@ struct ExtractorConfig
std::string rtree_leafs_output_path;
std::string profile_properties_output_path;
std::string intersection_class_data_output_path;
std::string turn_weight_penalties_path;
std::string turn_duration_penalties_path;
unsigned requested_num_threads;
unsigned small_component_size;
bool generate_edge_lookup;
std::string edge_penalty_path;
std::string turn_penalties_index_path;
std::string edge_segment_lookup_path;
bool use_metadata;
+49 -31
View File
@@ -1,15 +1,16 @@
#ifndef INTERNAL_EXTRACTOR_EDGE_HPP
#define INTERNAL_EXTRACTOR_EDGE_HPP
#include "extractor/guidance/road_classification.hpp"
#include "extractor/guidance/turn_lane_types.hpp"
#include "extractor/node_based_edge.hpp"
#include "extractor/travel_mode.hpp"
#include "osrm/coordinate.hpp"
#include "util/strong_typedef.hpp"
#include "util/typedefs.hpp"
#include <boost/assert.hpp>
#include "extractor/guidance/road_classification.hpp"
#include "extractor/guidance/turn_lane_types.hpp"
#include "osrm/coordinate.hpp"
#include <mapbox/variant.hpp>
#include <utility>
namespace osrm
@@ -17,31 +18,37 @@ namespace osrm
namespace extractor
{
namespace detail
{
// these are used for duration based mode of transportations like ferries
OSRM_STRONG_TYPEDEF(double, ValueByEdge)
OSRM_STRONG_TYPEDEF(double, ValueByMeter)
using ByEdgeOrByMeterValue = mapbox::util::variant<detail::ValueByEdge, detail::ValueByMeter>;
struct ToValueByEdge
{
ToValueByEdge(double distance_) : distance(distance_) {}
ValueByEdge operator()(const ValueByMeter by_meter) const
{
return ValueByEdge{distance / static_cast<double>(by_meter)};
}
ValueByEdge operator()(const ValueByEdge by_edge) const { return by_edge; }
double distance;
};
}
struct InternalExtractorEdge
{
// specify the type of the weight data
enum class WeightType : char
{
INVALID,
SPEED,
EDGE_DURATION,
WAY_DURATION,
};
struct WeightData
{
WeightData() : duration(0.0), type(WeightType::INVALID) {}
union {
double duration;
double speed;
};
WeightType type;
};
using WeightData = detail::ByEdgeOrByMeterValue;
using DurationData = detail::ByEdgeOrByMeterValue;
explicit InternalExtractorEdge()
: result(MIN_OSM_NODEID,
MIN_OSM_NODEID,
SPECIAL_NODEID,
0,
0,
false, // forward
@@ -52,7 +59,8 @@ struct InternalExtractorEdge
TRAVEL_MODE_INACCESSIBLE,
false,
guidance::TurnLaneType::empty,
guidance::RoadClassification())
guidance::RoadClassification()),
weight_data(detail::ValueByMeter{0.0}), duration_data(detail::ValueByMeter{0.0})
{
}
@@ -60,6 +68,7 @@ struct InternalExtractorEdge
OSMNodeID target,
NodeID name_id,
WeightData weight_data,
DurationData duration_data,
bool forward,
bool backward,
bool roundabout,
@@ -68,11 +77,13 @@ struct InternalExtractorEdge
TravelMode travel_mode,
bool is_split,
LaneDescriptionID lane_description,
guidance::RoadClassification road_classification)
guidance::RoadClassification road_classification,
util::Coordinate source_coordinate)
: result(source,
target,
name_id,
0,
0,
forward,
backward,
roundabout,
@@ -82,7 +93,8 @@ struct InternalExtractorEdge
is_split,
lane_description,
std::move(road_classification)),
weight_data(std::move(weight_data))
weight_data(std::move(weight_data)), duration_data(std::move(duration_data)),
source_coordinate(std::move(source_coordinate))
{
}
@@ -90,6 +102,8 @@ struct InternalExtractorEdge
NodeBasedEdgeWithOSM result;
// intermediate edge weight
WeightData weight_data;
// intermediate edge duration
DurationData duration_data;
// coordinate of the source node
util::Coordinate source_coordinate;
@@ -98,8 +112,9 @@ struct InternalExtractorEdge
{
return InternalExtractorEdge(MIN_OSM_NODEID,
MIN_OSM_NODEID,
0,
WeightData(),
SPECIAL_NODEID,
detail::ValueByMeter{0.0},
detail::ValueByMeter{0.0},
false, // forward
false, // backward
false, // roundabout
@@ -108,14 +123,16 @@ struct InternalExtractorEdge
TRAVEL_MODE_INACCESSIBLE,
false,
INVALID_LANE_DESCRIPTIONID,
guidance::RoadClassification());
guidance::RoadClassification(),
util::Coordinate());
}
static InternalExtractorEdge max_osm_value()
{
return InternalExtractorEdge(MAX_OSM_NODEID,
MAX_OSM_NODEID,
SPECIAL_NODEID,
WeightData(),
detail::ValueByMeter{0.0},
detail::ValueByMeter{0.0},
false, // forward
false, // backward
false, // roundabout
@@ -124,7 +141,8 @@ struct InternalExtractorEdge
TRAVEL_MODE_INACCESSIBLE,
false,
INVALID_LANE_DESCRIPTIONID,
guidance::RoadClassification());
guidance::RoadClassification(),
util::Coordinate());
}
static InternalExtractorEdge min_internal_value()
+25 -13
View File
@@ -19,6 +19,7 @@ struct NodeBasedEdge
NodeID target,
NodeID name_id,
EdgeWeight weight,
EdgeWeight duration,
bool forward,
bool backward,
bool roundabout,
@@ -35,12 +36,13 @@ struct NodeBasedEdge
NodeID target;
NodeID name_id;
EdgeWeight weight;
bool forward : 1;
bool backward : 1;
bool roundabout : 1;
bool circular : 1;
bool startpoint : 1;
bool is_split : 1;
EdgeWeight duration;
std::uint8_t forward : 1;
std::uint8_t backward : 1;
std::uint8_t roundabout : 1;
std::uint8_t circular : 1;
std::uint8_t startpoint : 1;
std::uint8_t is_split : 1;
TravelMode travel_mode : 4;
LaneDescriptionID lane_description_id;
guidance::RoadClassification road_classification;
@@ -52,6 +54,7 @@ struct NodeBasedEdgeWithOSM : NodeBasedEdge
OSMNodeID target,
NodeID name_id,
EdgeWeight weight,
EdgeWeight duration,
bool forward,
bool backward,
bool roundabout,
@@ -69,9 +72,10 @@ struct NodeBasedEdgeWithOSM : NodeBasedEdge
// Impl.
inline NodeBasedEdge::NodeBasedEdge()
: source(SPECIAL_NODEID), target(SPECIAL_NODEID), name_id(0), weight(0), forward(false),
backward(false), roundabout(false), circular(false), startpoint(true), is_split(false),
travel_mode(false), lane_description_id(INVALID_LANE_DESCRIPTIONID)
: source(SPECIAL_NODEID), target(SPECIAL_NODEID), name_id(0), weight(0), duration(0),
forward(false), backward(false), roundabout(false), circular(false), startpoint(true),
is_split(false), travel_mode(TRAVEL_MODE_INACCESSIBLE),
lane_description_id(INVALID_LANE_DESCRIPTIONID)
{
}
@@ -79,6 +83,7 @@ inline NodeBasedEdge::NodeBasedEdge(NodeID source,
NodeID target,
NodeID name_id,
EdgeWeight weight,
EdgeWeight duration,
bool forward,
bool backward,
bool roundabout,
@@ -88,10 +93,10 @@ inline NodeBasedEdge::NodeBasedEdge(NodeID source,
bool is_split,
const LaneDescriptionID lane_description_id,
guidance::RoadClassification road_classification)
: source(source), target(target), name_id(name_id), weight(weight), forward(forward),
backward(backward), roundabout(roundabout), circular(circular), startpoint(startpoint),
is_split(is_split), travel_mode(travel_mode), lane_description_id(lane_description_id),
road_classification(std::move(road_classification))
: source(source), target(target), name_id(name_id), weight(weight), duration(duration),
forward(forward), backward(backward), roundabout(roundabout), circular(circular),
startpoint(startpoint), is_split(is_split), travel_mode(travel_mode),
lane_description_id(lane_description_id), road_classification(std::move(road_classification))
{
}
@@ -116,6 +121,7 @@ inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM(OSMNodeID source,
OSMNodeID target,
NodeID name_id,
EdgeWeight weight,
EdgeWeight duration,
bool forward,
bool backward,
bool roundabout,
@@ -129,6 +135,7 @@ inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM(OSMNodeID source,
SPECIAL_NODEID,
name_id,
weight,
duration,
forward,
backward,
roundabout,
@@ -142,6 +149,11 @@ inline NodeBasedEdgeWithOSM::NodeBasedEdgeWithOSM(OSMNodeID source,
{
}
static_assert(sizeof(extractor::NodeBasedEdge) == 28,
"Size of extractor::NodeBasedEdge type is "
"bigger than expected. This will influence "
"memory consumption.");
} // ns extractor
} // ns osrm
+36 -3
View File
@@ -1,6 +1,8 @@
#ifndef PROFILE_PROPERTIES_HPP
#define PROFILE_PROPERTIES_HPP
#include <algorithm>
#include <boost/assert.hpp>
#include <boost/numeric/conversion/cast.hpp>
namespace osrm
@@ -12,11 +14,18 @@ const constexpr auto DEFAULT_MAX_SPEED = 180 / 3.6; // 180kmph -> m/s
struct ProfileProperties
{
enum
{
MAX_WEIGHT_NAME_LENGTH = 255
};
ProfileProperties()
: traffic_signal_penalty(0), u_turn_penalty(0),
max_speed_for_map_matching(DEFAULT_MAX_SPEED), continue_straight_at_waypoint(true),
use_turn_restrictions(false), left_hand_driving(false)
use_turn_restrictions(false), left_hand_driving(false), fallback_to_duration(true),
weight_name{"duration"}
{
BOOST_ASSERT(weight_name[MAX_WEIGHT_NAME_LENGTH] == '\0');
}
double GetUturnPenalty() const { return u_turn_penalty / 10.; }
@@ -40,14 +49,38 @@ struct ProfileProperties
max_speed_for_map_matching = max_speed_for_map_matching_;
}
void SetWeightName(const std::string &name)
{
auto count = std::min<std::size_t>(name.length(), MAX_WEIGHT_NAME_LENGTH) + 1;
std::copy_n(name.c_str(), count, weight_name);
// Make sure this is always zero terminated
BOOST_ASSERT(weight_name[count - 1] == '\0');
BOOST_ASSERT(weight_name[MAX_WEIGHT_NAME_LENGTH] == '\0');
// Set lazy fallback flag
fallback_to_duration = name == "duration";
}
std::string GetWeightName() const
{
// Make sure this is always zero terminated
BOOST_ASSERT(weight_name[MAX_WEIGHT_NAME_LENGTH] == '\0');
return std::string(weight_name);
}
//! penalty to cross a traffic light in deci-seconds
int traffic_signal_penalty;
std::int32_t traffic_signal_penalty;
//! penalty to do a uturn in deci-seconds
int u_turn_penalty;
std::int32_t u_turn_penalty;
double max_speed_for_map_matching;
//! depending on the profile, force the routing to always continue in the same direction
bool continue_straight_at_waypoint;
//! flag used for restriction parser (e.g. used for the walk profile)
bool use_turn_restrictions;
bool left_hand_driving;
bool fallback_to_duration;
//! stores the name of the weight (e.g. 'duration', 'distance', 'safety')
char weight_name[MAX_WEIGHT_NAME_LENGTH + 1];
unsigned weight_precision = 1;
};
}
}
+5 -5
View File
@@ -35,6 +35,8 @@ namespace extractor
class RestrictionParser;
struct ExtractionNode;
struct ExtractionWay;
struct ExtractionTurn;
struct ExtractionSegment;
/**
* Abstract class that handles processing osmium ways, nodes and relation objects by applying
@@ -53,11 +55,9 @@ class ScriptingEnvironment
virtual std::vector<std::string> GetNameSuffixList() = 0;
virtual std::vector<std::string> GetRestrictions() = 0;
virtual void SetupSources() = 0;
virtual int32_t GetTurnPenalty(double angle) = 0;
virtual void ProcessSegment(const osrm::util::Coordinate &source,
const osrm::util::Coordinate &target,
double distance,
InternalExtractorEdge::WeightData &weight) = 0;
virtual void ProcessTurn(ExtractionTurn &turn) = 0;
virtual void ProcessSegment(ExtractionSegment &segment) = 0;
virtual void
ProcessElements(const std::vector<osmium::memory::Buffer::const_iterator> &osm_elements,
const RestrictionParser &restriction_parser,
@@ -45,7 +45,7 @@ class Sol2ScriptingEnvironment final : public ScriptingEnvironment
{
public:
static const constexpr int SUPPORTED_MIN_API_VERSION = 0;
static const constexpr int SUPPORTED_MAX_API_VERSION = 0;
static const constexpr int SUPPORTED_MAX_API_VERSION = 1;
explicit Sol2ScriptingEnvironment(const std::string &file_name);
~Sol2ScriptingEnvironment() override = default;
@@ -57,11 +57,9 @@ class Sol2ScriptingEnvironment final : public ScriptingEnvironment
std::vector<std::string> GetNameSuffixList() override;
std::vector<std::string> GetRestrictions() override;
void SetupSources() override;
int32_t GetTurnPenalty(double angle) override;
void ProcessSegment(const osrm::util::Coordinate &source,
const osrm::util::Coordinate &target,
double distance,
InternalExtractorEdge::WeightData &weight) override;
void ProcessTurn(ExtractionTurn &turn) override;
void ProcessSegment(ExtractionSegment &segment) override;
void
ProcessElements(const std::vector<osmium::memory::Buffer::const_iterator> &osm_elements,
const RestrictionParser &restriction_parser,
+3 -1
View File
@@ -28,6 +28,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef TRAVEL_MODE_HPP
#define TRAVEL_MODE_HPP
#include <cstdint>
namespace osrm
{
namespace extractor
@@ -35,7 +37,7 @@ namespace extractor
// This is a char instead of a typed enum, so that we can
// pack it into e.g. a "TravelMode mode : 4" packed bitfield
using TravelMode = unsigned char;
using TravelMode = std::uint8_t;
}
}