Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Byko-Ianko <v.bykoianko@corp.mail.ru>2018-11-10 14:52:15 +0300
committermpimenov <mpimenov@users.noreply.github.com>2018-11-23 17:58:49 +0300
commit1a9c5d3d09b297f1343e12172a8bd0833373a799 (patch)
tree13e55dd1b4abdb5a9dacca740f923e115d953913 /routing_common
parent977252247077460fd02b46ccd72cad8b768ddc40 (diff)
[routing] Getting ready VehicleModel for bidirectinal maxspeeds.
Diffstat (limited to 'routing_common')
-rw-r--r--routing_common/CMakeLists.txt2
-rw-r--r--routing_common/maxspeed_conversion.cpp278
-rw-r--r--routing_common/maxspeed_conversion.hpp253
-rw-r--r--routing_common/vehicle_model.cpp5
-rw-r--r--routing_common/vehicle_model.hpp9
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;