diff options
author | Vladimir Byko-Ianko <v.bykoianko@corp.mail.ru> | 2018-11-10 14:52:15 +0300 |
---|---|---|
committer | mpimenov <mpimenov@users.noreply.github.com> | 2018-11-23 17:58:49 +0300 |
commit | 1a9c5d3d09b297f1343e12172a8bd0833373a799 (patch) | |
tree | 13e55dd1b4abdb5a9dacca740f923e115d953913 /routing_common | |
parent | 977252247077460fd02b46ccd72cad8b768ddc40 (diff) |
[routing] Getting ready VehicleModel for bidirectinal maxspeeds.
Diffstat (limited to 'routing_common')
-rw-r--r-- | routing_common/CMakeLists.txt | 2 | ||||
-rw-r--r-- | routing_common/maxspeed_conversion.cpp | 278 | ||||
-rw-r--r-- | routing_common/maxspeed_conversion.hpp | 253 | ||||
-rw-r--r-- | routing_common/vehicle_model.cpp | 5 | ||||
-rw-r--r-- | routing_common/vehicle_model.hpp | 9 |
5 files changed, 544 insertions, 3 deletions
diff --git a/routing_common/CMakeLists.txt b/routing_common/CMakeLists.txt index 2390fda58f..ca7a735b61 100644 --- a/routing_common/CMakeLists.txt +++ b/routing_common/CMakeLists.txt @@ -10,6 +10,8 @@ set( bicycle_model.hpp car_model.cpp car_model.hpp + maxspeed_conversion.cpp + maxspeed_conversion.hpp num_mwm_id.hpp pedestrian_model.cpp pedestrian_model.hpp diff --git a/routing_common/maxspeed_conversion.cpp b/routing_common/maxspeed_conversion.cpp new file mode 100644 index 0000000000..0677fbbf11 --- /dev/null +++ b/routing_common/maxspeed_conversion.cpp @@ -0,0 +1,278 @@ +#include "routing_common/maxspeed_conversion.hpp" + +#include <sstream> +#include <utility> + +namespace routing +{ +using namespace measurement_utils; + +// SpeedInUnits ------------------------------------------------------------------------------------ +bool SpeedInUnits::operator==(SpeedInUnits const & rhs) const +{ + return m_speed == rhs.m_speed && m_units == rhs.m_units; +} + +bool SpeedInUnits::operator<(SpeedInUnits const & rhs) const +{ + return (m_units == Units::Metric ? m_speed : MphToKmph(m_speed)) < + (rhs.m_units == Units::Metric ? rhs.m_speed : MphToKmph(rhs.m_speed)); +} + +bool SpeedInUnits::IsNumeric() const +{ + return m_speed != kNoneMaxSpeed && m_speed != kWalkMaxSpeed && m_speed != kInvalidSpeed; +} + +// FeatureMaxspeed --------------------------------------------------------------------------------- +FeatureMaxspeed::FeatureMaxspeed(uint32_t fid, measurement_utils::Units units, uint16_t forward, + uint16_t backward /* = kInvalidSpeed */) noexcept + : m_featureId(fid), m_maxspeed({units, forward, backward}) +{ +} + +bool FeatureMaxspeed::operator==(FeatureMaxspeed const & rhs) const +{ + return m_featureId == rhs.m_featureId && m_maxspeed == rhs.m_maxspeed; +} + +SpeedInUnits FeatureMaxspeed::GetForwardSpeedInUnits() const +{ + return SpeedInUnits(GetMaxspeed().m_forward, GetMaxspeed().m_units); +} + +SpeedInUnits FeatureMaxspeed::GetBackwardSpeedInUnits() const +{ + return SpeedInUnits(GetMaxspeed().m_backward, GetMaxspeed().m_units); +} + +// MaxspeedConverter ------------------------------------------------------------------------------- +MaxspeedConverter::MaxspeedConverter() +{ + // Special values. + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Undefined)] = SpeedInUnits(kInvalidSpeed, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::None)] = SpeedInUnits(kNoneMaxSpeed, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Walk)] = SpeedInUnits(kWalkMaxSpeed, Units::Metric); + + // Km per hour. + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed1kph)] = SpeedInUnits(1, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed2kph)] = SpeedInUnits(2, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed3kph)] = SpeedInUnits(3, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed4kph)] = SpeedInUnits(4, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed5kph)] = SpeedInUnits(5, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed6kph)] = SpeedInUnits(6, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed7kph)] = SpeedInUnits(7, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed8kph)] = SpeedInUnits(8, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed9kph)] = SpeedInUnits(9, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed10kph)] = SpeedInUnits(10, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed11kph)] = SpeedInUnits(11, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed12kph)] = SpeedInUnits(12, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed13kph)] = SpeedInUnits(13, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed14kph)] = SpeedInUnits(14, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed15kph)] = SpeedInUnits(15, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed16kph)] = SpeedInUnits(16, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed18kph)] = SpeedInUnits(18, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed20kph)] = SpeedInUnits(20, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed22kph)] = SpeedInUnits(22, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed25kph)] = SpeedInUnits(25, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed24kph)] = SpeedInUnits(24, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed28kph)] = SpeedInUnits(28, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed30kph)] = SpeedInUnits(30, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed32kph)] = SpeedInUnits(32, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed35kph)] = SpeedInUnits(35, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed36kph)] = SpeedInUnits(36, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed39kph)] = SpeedInUnits(39, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed40kph)] = SpeedInUnits(40, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed45kph)] = SpeedInUnits(45, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed50kph)] = SpeedInUnits(50, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed55kph)] = SpeedInUnits(55, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed56kph)] = SpeedInUnits(56, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed60kph)] = SpeedInUnits(60, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed64kph)] = SpeedInUnits(64, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed65kph)] = SpeedInUnits(65, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed70kph)] = SpeedInUnits(70, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed72kph)] = SpeedInUnits(72, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed75kph)] = SpeedInUnits(75, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed80kph)] = SpeedInUnits(80, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed82kph)] = SpeedInUnits(82, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed85kph)] = SpeedInUnits(85, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed89kph)] = SpeedInUnits(89, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed90kph)] = SpeedInUnits(90, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed93kph)] = SpeedInUnits(93, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed95kph)] = SpeedInUnits(95, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed96kph)] = SpeedInUnits(96, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed100kph)] = SpeedInUnits(100, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed104kph)] = SpeedInUnits(104, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed105kph)] = SpeedInUnits(105, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed106kph)] = SpeedInUnits(106, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed110kph)] = SpeedInUnits(110, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed112kph)] = SpeedInUnits(112, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed115kph)] = SpeedInUnits(115, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed120kph)] = SpeedInUnits(120, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed125kph)] = SpeedInUnits(125, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed127kph)] = SpeedInUnits(127, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed130kph)] = SpeedInUnits(130, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed135kph)] = SpeedInUnits(135, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed140kph)] = SpeedInUnits(140, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed141kph)] = SpeedInUnits(141, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed145kph)] = SpeedInUnits(145, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed150kph)] = SpeedInUnits(150, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed155kph)] = SpeedInUnits(155, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed160kph)] = SpeedInUnits(160, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed165kph)] = SpeedInUnits(165, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed170kph)] = SpeedInUnits(170, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed177kph)] = SpeedInUnits(177, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed180kph)] = SpeedInUnits(180, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed185kph)] = SpeedInUnits(185, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed190kph)] = SpeedInUnits(190, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed193kph)] = SpeedInUnits(193, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed195kph)] = SpeedInUnits(195, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed200kph)] = SpeedInUnits(200, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed201kph)] = SpeedInUnits(201, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed210kph)] = SpeedInUnits(210, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed217kph)] = SpeedInUnits(217, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed220kph)] = SpeedInUnits(220, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed230kph)] = SpeedInUnits(230, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed240kph)] = SpeedInUnits(240, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed250kph)] = SpeedInUnits(250, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed260kph)] = SpeedInUnits(260, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed270kph)] = SpeedInUnits(270, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed275kph)] = SpeedInUnits(275, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed280kph)] = SpeedInUnits(280, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed285kph)] = SpeedInUnits(285, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed300kph)] = SpeedInUnits(300, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed305kph)] = SpeedInUnits(305, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed310kph)] = SpeedInUnits(310, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed320kph)] = SpeedInUnits(320, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed350kph)] = SpeedInUnits(350, Units::Metric); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed380kph)] = SpeedInUnits(380, Units::Metric); + + // Mile per hours. + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed3mph)] = SpeedInUnits(3, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed4mph)] = SpeedInUnits(4, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed5mph)] = SpeedInUnits(5, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed6mph)] = SpeedInUnits(6, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed7mph)] = SpeedInUnits(7, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed8mph)] = SpeedInUnits(8, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed9mph)] = SpeedInUnits(9, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed10mph)] = SpeedInUnits(10, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed12mph)] = SpeedInUnits(12, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed13mph)] = SpeedInUnits(13, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed14mph)] = SpeedInUnits(14, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed15mph)] = SpeedInUnits(15, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed17mph)] = SpeedInUnits(17, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed18mph)] = SpeedInUnits(18, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed19mph)] = SpeedInUnits(19, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed20mph)] = SpeedInUnits(20, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed24mph)] = SpeedInUnits(24, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed25mph)] = SpeedInUnits(25, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed30mph)] = SpeedInUnits(30, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed35mph)] = SpeedInUnits(35, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed40mph)] = SpeedInUnits(40, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed45mph)] = SpeedInUnits(45, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed50mph)] = SpeedInUnits(50, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed55mph)] = SpeedInUnits(55, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed59mph)] = SpeedInUnits(59, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed60mph)] = SpeedInUnits(60, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed65mph)] = SpeedInUnits(65, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed70mph)] = SpeedInUnits(70, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed75mph)] = SpeedInUnits(75, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed79mph)] = SpeedInUnits(79, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed80mph)] = SpeedInUnits(80, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed85mph)] = SpeedInUnits(85, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed90mph)] = SpeedInUnits(90, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed95mph)] = SpeedInUnits(95, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed100mph)] = SpeedInUnits(100, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed105mph)] = SpeedInUnits(105, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed110mph)] = SpeedInUnits(110, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed115mph)] = SpeedInUnits(115, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed120mph)] = SpeedInUnits(120, Units::Imperial); + m_macroToSpeed[static_cast<uint8_t>(SpeedMacro::Speed125mph)] = SpeedInUnits(125, Units::Imperial); + + m_speedToMacro.insert(std::make_pair(SpeedInUnits(kInvalidSpeed, Units::Metric), SpeedMacro::Undefined)); + for (size_t i = 1; i < std::numeric_limits<uint8_t>::max(); ++i) + { + auto const & speed = m_macroToSpeed[i]; + if (!speed.IsValid()) + continue; + + m_speedToMacro.insert(std::make_pair(speed, static_cast<SpeedMacro>(i))); + } +} + +SpeedInUnits MaxspeedConverter::MacroToSpeed(SpeedMacro macro) const +{ + return m_macroToSpeed[static_cast<uint8_t>(macro)]; +} + +SpeedMacro MaxspeedConverter::SpeedToMacro(SpeedInUnits const & speed) const +{ + auto const it = m_speedToMacro.find(speed); + if (it == m_speedToMacro.cend()) + { + // Note. On the feature emitting step we emit a maxspeed value with maxspeed:forward and + // maxspeed:backward only if forward and backward have the same units or one or two of them + // have a special value ("none", "walk"). So if forward maxspeed is in imperial units + // and backward maxspeed has a special value (like "none"), we may get a line is csv + // like this "100,Imperial,100,65534". Conditions below is written to process such edge cases + // correctly. + if (speed == SpeedInUnits(kNoneMaxSpeed, Units::Imperial)) + return SpeedMacro::None; + if (speed == SpeedInUnits(kWalkMaxSpeed, Units::Imperial)) + return SpeedMacro::Walk; + + return SpeedMacro::Undefined; + } + + return it->second; +} + +bool MaxspeedConverter::IsValidMacro(uint8_t macro) const +{ + return m_macroToSpeed[macro].IsValid(); +} + +MaxspeedConverter const & GetMaxspeedConverter() +{ + static const MaxspeedConverter inst; + return inst; +} + +bool HaveSameUnits(SpeedInUnits const & lhs, SpeedInUnits const & rhs) +{ + return lhs.m_units == rhs.m_units || !lhs.IsNumeric() || !rhs.IsNumeric(); +} + +std::string DebugPrint(Maxspeed maxspeed) +{ + std::ostringstream oss; + oss << "Maxspeed [ m_units:" << DebugPrint(maxspeed.m_units) + << " m_forward:" << maxspeed.m_forward + << " m_backward:" << maxspeed.m_backward << " ]"; + return oss.str(); +} + +std::string DebugPrint(SpeedMacro maxspeed) +{ + std::ostringstream oss; + oss << "SpeedMacro:" << static_cast<int>(maxspeed) << " Decoded:" + << DebugPrint(GetMaxspeedConverter().MacroToSpeed(maxspeed)); + return oss.str(); +} + +std::string DebugPrint(SpeedInUnits const & speed) +{ + std::ostringstream oss; + oss << "SpeedInUnits [ m_speed == " << speed.m_speed + << ", m_units:" << DebugPrint(speed.m_units) << " ]"; + return oss.str(); +} + +std::string DebugPrint(FeatureMaxspeed const & featureMaxspeed) +{ + std::ostringstream oss; + oss << "FeatureMaxspeed [ m_featureId:" << featureMaxspeed.GetFeatureId() + << " m_maxspeed:" << DebugPrint(featureMaxspeed.GetMaxspeed()) << " ]"; + return oss.str(); +} +} // namespace routing diff --git a/routing_common/maxspeed_conversion.hpp b/routing_common/maxspeed_conversion.hpp new file mode 100644 index 0000000000..f855096600 --- /dev/null +++ b/routing_common/maxspeed_conversion.hpp @@ -0,0 +1,253 @@ +#pragma once + +#include "platform/measurement_utils.hpp" + +#include <array> +#include <cstdint> +#include <limits> +#include <map> +#include <string> + +namespace routing +{ +/// \brief This enum class contains most popular maxspeed value according to +/// https://taginfo.openstreetmap.org/keys/maxspeed#values. +/// \note Value of this enum is saved to mwm. So they should not be changed because of backward +/// compatibility. But it's possible to add some new values to this enum. +enum class SpeedMacro : uint8_t +{ + // Special values. + Undefined, + None, // No maxspeed restriction (E.g. a motorway in Germany). + Walk, // Driver should move as a walking person. + + // Km per hour. + Speed1kph = 10, + Speed2kph, + Speed3kph, + Speed4kph, + Speed5kph, + Speed6kph, + Speed7kph, + Speed8kph, + Speed9kph, + Speed10kph, + Speed11kph, + Speed12kph, + Speed13kph, + Speed14kph, + Speed15kph, + Speed16kph, + Speed18kph, + Speed20kph, + Speed22kph, + Speed25kph, + Speed24kph, + Speed28kph, + Speed30kph, + Speed32kph, + Speed35kph, + Speed36kph, + Speed39kph, + Speed40kph, + Speed45kph, + Speed50kph, + Speed55kph, + Speed56kph, + Speed60kph, + Speed64kph, + Speed65kph, + Speed70kph, + Speed72kph, + Speed75kph, + Speed80kph, + Speed82kph, + Speed85kph, + Speed89kph, + Speed90kph, + Speed93kph, + Speed95kph, + Speed96kph, + Speed100kph, + Speed104kph, + Speed105kph, + Speed106kph, + Speed110kph, + Speed112kph, + Speed115kph, + Speed120kph, + Speed125kph, + Speed127kph, + Speed130kph, + Speed135kph, + Speed140kph, + Speed141kph, + Speed145kph, + Speed150kph, + Speed155kph, + Speed160kph, + Speed165kph, + Speed170kph, + Speed177kph, + Speed180kph, + Speed185kph, + Speed190kph, + Speed193kph, + Speed195kph, + Speed200kph, + Speed201kph, + Speed210kph, + Speed217kph, + Speed220kph, + Speed230kph, + Speed240kph, + Speed250kph, + Speed260kph, + Speed270kph, + Speed275kph, + Speed280kph, + Speed285kph, + Speed300kph, + Speed305kph, + Speed310kph, + Speed320kph, + Speed350kph, + Speed380kph, + + // Mile per hours. + Speed3mph = 110, + Speed4mph, + Speed5mph, + Speed6mph, + Speed7mph, + Speed8mph, + Speed9mph, + Speed10mph, + Speed12mph, + Speed13mph, + Speed14mph, + Speed15mph, + Speed17mph, + Speed18mph, + Speed19mph, + Speed20mph, + Speed24mph, + Speed25mph, + Speed30mph, + Speed35mph, + Speed40mph, + Speed45mph, + Speed50mph, + Speed55mph, + Speed59mph, + Speed60mph, + Speed65mph, + Speed70mph, + Speed75mph, + Speed79mph, + Speed80mph, + Speed85mph, + Speed90mph, + Speed95mph, + Speed100mph, + Speed105mph, + Speed110mph, + Speed115mph, + Speed120mph, + Speed125mph, +}; + +uint16_t constexpr kInvalidSpeed = std::numeric_limits<uint16_t>::max(); +uint16_t constexpr kNoneMaxSpeed = std::numeric_limits<uint16_t>::max() - 1; +uint16_t constexpr kWalkMaxSpeed = std::numeric_limits<uint16_t>::max() - 2; + +struct SpeedInUnits +{ + SpeedInUnits() = default; + SpeedInUnits(uint16_t speed, measurement_utils::Units units) noexcept : m_speed(speed), m_units(units) {} + + bool operator==(SpeedInUnits const & rhs) const; + bool operator<(SpeedInUnits const & rhs) const; + + bool IsNumeric() const; + bool IsValid() const { return m_speed != kInvalidSpeed; } + + // Speed in km per hour or mile per hour depends on m_units value. + uint16_t m_speed = kInvalidSpeed; + // |m_units| is undefined in case of SpeedMacro::None and SpeedMacro::Walk. + measurement_utils::Units m_units = measurement_utils::Units::Metric; +}; + +struct Maxspeed +{ + measurement_utils::Units m_units = measurement_utils::Units::Metric; + // Speed in km per hour or mile per hour depends on |m_units|. + uint16_t m_forward = kInvalidSpeed; + // Speed in km per hour or mile per hour depends on |m_units|. + uint16_t m_backward = kInvalidSpeed; + + bool operator==(Maxspeed const & rhs) const + { + return m_units == rhs.m_units && m_forward == rhs.m_forward && m_backward == rhs.m_backward; + } + + bool IsValid() const { return m_forward != kInvalidSpeed; } + bool IsBidirectional() const { return IsValid() && m_backward != kInvalidSpeed; } +}; + +/// \brief Feature id and corresponding maxspeed tag value. |m_forward| and |m_backward| fields +/// reflect the fact that a feature may have different maxspeed tag value for different directions. +/// If |m_backward| is invalid it means that |m_forward| tag contains maxspeed for +/// the both directions. If a feature has maxspeed forward and maxspeed backward in different units +/// it's considered as an invalid one and it's not saved into mwm. +class FeatureMaxspeed +{ +public: + FeatureMaxspeed(uint32_t fid, measurement_utils::Units units, uint16_t forward, + uint16_t backward = kInvalidSpeed) noexcept; + + /// \note operator==() and operator<() do not correspond to each other. + bool operator==(FeatureMaxspeed const & rhs) const; + bool operator<(FeatureMaxspeed const & rhs) const { return m_featureId < rhs.m_featureId; } + + bool IsValid() const { return m_maxspeed.IsValid(); } + bool IsBidirectional() const { return m_maxspeed.IsBidirectional(); } + + uint32_t GetFeatureId() const { return m_featureId; } + Maxspeed const & GetMaxspeed() const { return m_maxspeed; } + + SpeedInUnits GetForwardSpeedInUnits() const; + SpeedInUnits GetBackwardSpeedInUnits() const; + +private: + uint32_t m_featureId = 0; + Maxspeed m_maxspeed; +}; + +class MaxspeedConverter +{ + friend MaxspeedConverter const & GetMaxspeedConverter(); +public: + MaxspeedConverter(); + + SpeedInUnits MacroToSpeed(SpeedMacro macro) const; + SpeedMacro SpeedToMacro(SpeedInUnits const & speed) const; + + /// \returns true if |macro| can be cast to a valid value of SpeedMacro emum class. + /// \note SpeedMacro::Undefined value and all values from 1 to 256 which are not present + /// in SpeedMacro enum class are considered as an invalid. + bool IsValidMacro(uint8_t macro) const; + +private: + std::array<SpeedInUnits, std::numeric_limits<uint8_t>::max()> m_macroToSpeed; + std::map<SpeedInUnits, SpeedMacro> m_speedToMacro; +}; + +MaxspeedConverter const & GetMaxspeedConverter(); +bool HaveSameUnits(SpeedInUnits const & lhs, SpeedInUnits const & rhs); + +std::string DebugPrint(Maxspeed maxspeed); +std::string DebugPrint(SpeedMacro maxspeed); +std::string DebugPrint(SpeedInUnits const & speed); +std::string DebugPrint(FeatureMaxspeed const & featureMaxspeed); +} // namespace routing diff --git a/routing_common/vehicle_model.cpp b/routing_common/vehicle_model.cpp index c583c5f122..d9e957d829 100644 --- a/routing_common/vehicle_model.cpp +++ b/routing_common/vehicle_model.cpp @@ -1,5 +1,7 @@ #include "routing_common/vehicle_model.hpp" +#include "routing_common/maxspeed_conversion.hpp" + #include "indexer/classificator.hpp" #include "indexer/feature.hpp" #include "indexer/ftypes_matcher.hpp" @@ -87,7 +89,8 @@ void VehicleModel::SetAdditionalRoadTypes(Classificator const & c, } } -VehicleModel::SpeedKMpH VehicleModel::GetSpeed(FeatureType & f, bool inCity) const +VehicleModel::SpeedKMpH VehicleModel::GetSpeed(FeatureType & f, bool forward, bool inCity, + Maxspeed const & maxspeed) const { feature::TypesHolder const types(f); diff --git a/routing_common/vehicle_model.hpp b/routing_common/vehicle_model.hpp index 877f459368..d48c28362c 100644 --- a/routing_common/vehicle_model.hpp +++ b/routing_common/vehicle_model.hpp @@ -16,6 +16,7 @@ namespace feature { class TypesHolder; } namespace routing { +struct Maxspeed; class VehicleModelInterface { @@ -39,6 +40,8 @@ public: return m_weight == rhs.m_weight && m_eta == rhs.m_eta; } + bool IsValid() const { return m_weight >= 0 && m_eta >= 0; } + double m_weight = 0.0; // KMpH double m_eta = 0.0; // KMpH }; @@ -72,7 +75,8 @@ public: /// @return Allowed weight and ETA speed in KMpH. /// 0 means that it's forbidden to move on this feature or it's not a road at all. /// @param inCity is true if |f| lies in a city of town. - virtual SpeedKMpH GetSpeed(FeatureType & f, bool inCity) const = 0; + virtual SpeedKMpH GetSpeed(FeatureType & f, bool forward, bool inCity, + Maxspeed const & maxspeed) const = 0; virtual double GetMaxWeightSpeed() const = 0; @@ -158,7 +162,8 @@ public: SurfaceInitList const & featureTypeSurface); /// VehicleModelInterface overrides: - SpeedKMpH GetSpeed(FeatureType & f, bool inCity) const override; + SpeedKMpH GetSpeed(FeatureType & f, bool forward, bool inCity, + Maxspeed const & maxspeed) const override; double GetMaxWeightSpeed() const override; bool IsOneWay(FeatureType & f) const override; bool IsRoad(FeatureType & f) const override; |