diff --git a/generator/CMakeLists.txt b/generator/CMakeLists.txt index 01e2171246..2cbd2e7ff5 100644 --- a/generator/CMakeLists.txt +++ b/generator/CMakeLists.txt @@ -19,6 +19,8 @@ set(SRC camera_info_collector.hpp camera_node_processor.cpp camera_node_processor.hpp + category_to_speed.cpp + category_to_speed.hpp centers_table_builder.cpp centers_table_builder.hpp check_model.cpp diff --git a/generator/camera_node_processor.cpp b/generator/camera_node_processor.cpp index ffb54a38d1..4ea6ca79c4 100644 --- a/generator/camera_node_processor.cpp +++ b/generator/camera_node_processor.cpp @@ -1,5 +1,9 @@ #include "generator/camera_node_processor.hpp" +#include "generator/category_to_speed.hpp" + +#include "platform/measurement_utils.hpp" + #include "base/assert.hpp" #include "base/control_flow.hpp" #include "base/logging.hpp" @@ -8,74 +12,6 @@ namespace generator { -// Look to https://wiki.openstreetmap.org/wiki/Speed_limits -// Remember about updating this table! Last update: 21.08.18 -std::unordered_map const kRoadTypeToSpeedKMpH = { - {"AT:urban", "50"}, - {"AT:rural", "100"}, - {"AT:trunk", "100"}, - {"AT:motorway", "130"}, - {"BE:urban", "50"}, - {"BE:zone", "30"}, - {"BE:motorway", "120"}, - {"BE:zone30", "30"}, - {"BE:rural", "70"}, - {"BE:school", "30"}, - {"CZ:motorway", "130"}, - {"CZ:trunk", "110"}, - {"CZ:rural", "90"}, - {"CZ:urban_motorway", "80"}, - {"CZ:urban_trunk", "80"}, - {"CZ:urban", "50"}, - {"DE:rural", "100"}, - {"DE:urban", "50"}, - {"DE:bicycle_road", "30"}, - {"FR:motorway", "130"}, - {"FR:rural", "80"}, - {"FR:urban", "50"}, - {"HU:living_street", "20"}, - {"HU:motorway", "130"}, - {"HU:rural", "90"}, - {"HU:trunk", "110"}, - {"HU:urban", "50"}, - {"IT:rural", "90"}, - {"IT:motorway", "130"}, - {"IT:urban", "50"}, - {"JP:nsl", "60"}, - {"JP:express", "100"}, - {"LT:rural", "90"}, - {"LT:urban", "50"}, - {"NO:rural", "80"}, - {"NO:urban", "50"}, - {"ON:urban", "50"}, - {"ON:rural", "80"}, - {"PT:motorway", "120"}, - {"PT:rural", "90"}, - {"PT:trunk", "100"}, - {"PT:urban", "50"}, - {"RO:motorway", "130"}, - {"RO:rural", "90"}, - {"RO:trunk", "100"}, - {"RO:urban", "50"}, - {"RU:living_street", "20"}, - {"RU:urban", "60"}, - {"RU:rural", "90"}, - {"RU:motorway", "110"}, - - {"GB:motorway", "112"}, // 70 mph = 112.65408 kmph - {"GB:nsl_dual", "112"}, // 70 mph = 112.65408 kmph - {"GB:nsl_single", "96"}, // 60 mph = 96.56064 kmph - - {"UK:motorway", "112"}, // 70 mph - {"UK:nsl_dual", "112"}, // 70 mph - {"UK:nsl_single", "96"}, // 60 mph - - {"UZ:living_street", "30"}, - {"UZ:urban", "70"}, - {"UZ:rural", "100"}, - {"UZ:motorway", "110"}, -}; - size_t const CameraNodeIntermediateDataProcessor::kMaxSpeedSpeedStringLength = 32; } // namespace generator @@ -178,9 +114,10 @@ void CameraNodeIntermediateDataProcessor::ProcessWay(uint64_t id, WayElement con std::string CameraNodeIntermediateDataProcessor::ValidateMaxSpeedString(std::string const & maxSpeedString) { - auto const it = kRoadTypeToSpeedKMpH.find(maxSpeedString); - if (it != kRoadTypeToSpeedKMpH.cend()) - return it->second; + double speed = 0.0; + measurement_utils::Units units = measurement_utils::Units::Metric; + if (RoadCategoryToSpeed(maxSpeedString, speed, units)) + return strings::to_string(static_cast(measurement_utils::ToSpeedKmPH(speed, units))); // strings::to_int doesn't work here because of bad errno. std::string result; @@ -205,7 +142,7 @@ std::string CameraNodeIntermediateDataProcessor::ValidateMaxSpeedString(std::str if (!strings::to_int(result.c_str(), mph)) return string(); - auto const kmh = static_cast(routing::MilesPH2KMPH(mph)); + auto const kmh = static_cast(measurement_utils::MphToKmph(mph)); return strings::to_string(kmh); } diff --git a/generator/camera_node_processor.hpp b/generator/camera_node_processor.hpp index f541f728c8..6f16326686 100644 --- a/generator/camera_node_processor.hpp +++ b/generator/camera_node_processor.hpp @@ -19,7 +19,6 @@ #include #include #include -#include #include // TODO (@gmoryes) move members of m_routingTagsProcessor to generator diff --git a/generator/category_to_speed.cpp b/generator/category_to_speed.cpp new file mode 100644 index 0000000000..997b0edb90 --- /dev/null +++ b/generator/category_to_speed.cpp @@ -0,0 +1,97 @@ +#include "generator/category_to_speed.hpp" + +#include + +namespace +{ +using namespace measurement_utils; + +struct Speed +{ + Speed() = delete; + + uint16_t m_speed; + Units m_units; +}; + +std::unordered_map const kRoadCategoryToSpeedKMpH = { + {"AT:urban", {50, Units::Metric}}, + {"AT:rural", {100, Units::Metric}}, + {"AT:trunk", {100, Units::Metric}}, + {"AT:motorway", {130, Units::Metric}}, + {"BE:urban", {50, Units::Metric}}, + {"BE:zone", {30, Units::Metric}}, + {"BE:motorway", {120, Units::Metric}}, + {"BE:zone30", {30, Units::Metric}}, + {"BE:rural", {70, Units::Metric}}, + {"BE:school", {30, Units::Metric}}, + {"CZ:motorway", {130, Units::Metric}}, + {"CZ:trunk", {110, Units::Metric}}, + {"CZ:rural", {90, Units::Metric}}, + {"CZ:urban_motorway", {80, Units::Metric}}, + {"CZ:urban_trunk", {80, Units::Metric}}, + {"CZ:urban", {50, Units::Metric}}, + {"DE:rural", {100, Units::Metric}}, + {"DE:urban", {50, Units::Metric}}, + {"DE:bicycle_road", {30, Units::Metric}}, + {"FR:motorway", {130, Units::Metric}}, + {"FR:rural", {80, Units::Metric}}, + {"FR:urban", {50, Units::Metric}}, + {"HU:living_street", {20, Units::Metric}}, + {"HU:motorway", {130, Units::Metric}}, + {"HU:rural", {90, Units::Metric}}, + {"HU:trunk", {110, Units::Metric}}, + {"HU:urban", {50, Units::Metric}}, + {"IT:rural", {90, Units::Metric}}, + {"IT:motorway", {130, Units::Metric}}, + {"IT:urban", {50, Units::Metric}}, + {"JP:nsl", {60, Units::Metric}}, + {"JP:express", {100, Units::Metric}}, + {"LT:rural", {90, Units::Metric}}, + {"LT:urban", {50, Units::Metric}}, + {"NO:rural", {80, Units::Metric}}, + {"NO:urban", {50, Units::Metric}}, + {"ON:urban", {50, Units::Metric}}, + {"ON:rural", {80, Units::Metric}}, + {"PT:motorway", {120, Units::Metric}}, + {"PT:rural", {90, Units::Metric}}, + {"PT:trunk", {100, Units::Metric}}, + {"PT:urban", {50, Units::Metric}}, + {"RO:motorway", {130, Units::Metric}}, + {"RO:rural", {90, Units::Metric}}, + {"RO:trunk", {100, Units::Metric}}, + {"RO:urban", {50, Units::Metric}}, + {"RU:living_street", {20, Units::Metric}}, + {"RU:urban", {60, Units::Metric}}, + {"RU:rural", {90, Units::Metric}}, + {"RU:motorway", {110, Units::Metric}}, + + {"GB:motorway", {70, Units::Imperial}}, // 70 mph = 112.65408 kmph + {"GB:nsl_dual", {70, Units::Imperial}}, // 70 mph = 112.65408 kmph + {"GB:nsl_single", {60, Units::Imperial}}, // 60 mph = 96.56064 kmph + + {"UK:motorway", {70, Units::Imperial}}, // 70 mph + {"UK:nsl_dual", {70, Units::Imperial}}, // 70 mph + {"UK:nsl_single", {60, Units::Imperial}}, // 60 mph + + {"UZ:living_street", {30, Units::Metric}}, + {"UZ:urban", {70, Units::Metric}}, + {"UZ:rural", {100, Units::Metric}}, + {"UZ:motorway", {110, Units::Metric}}, +}; +} // namespace + +namespace generator +{ +bool RoadCategoryToSpeed(std::string const & category, double & speed, + measurement_utils::Units & units) +{ + auto const it = kRoadCategoryToSpeedKMpH.find(category); + if (it == kRoadCategoryToSpeedKMpH.cend()) + return false; + + speed = it->second.m_speed; + units = it->second.m_units; + return true; +} +} // generator diff --git a/generator/category_to_speed.hpp b/generator/category_to_speed.hpp new file mode 100644 index 0000000000..c76da89980 --- /dev/null +++ b/generator/category_to_speed.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include "platform/measurement_utils.hpp" + +#include + +namespace generator +{ +/// \brief Obtains |speed| and |units| by road category based on +/// the table in https://wiki.openstreetmap.org/wiki/Speed_limits +/// This method should be updated regularly. Last update: 22.10.18. +/// \note For example by passing string "RU:urban", you'll get +/// speed = 60 and units = Units::Metric. +/// \returns true if |speed| and |units| is found for |category| and these fields are filled +/// and false otherwise. +bool RoadCategoryToSpeed(std::string const & category, double & speed, + measurement_utils::Units & units); +} // generator diff --git a/platform/measurement_utils.cpp b/platform/measurement_utils.cpp index 8c7b70ca73..60b0d7d8c4 100644 --- a/platform/measurement_utils.cpp +++ b/platform/measurement_utils.cpp @@ -52,6 +52,16 @@ bool FormatDistanceImpl(double m, string & res, return true; } +double ToSpeedKmPH(double speed, measurement_utils::Units units) +{ + switch (units) + { + case Units::Imperial: return MphToKmph(speed); + case Units::Metric: return speed; + } + CHECK_SWITCH(); +} + bool FormatDistance(double m, string & res) { auto units = Units::Metric; diff --git a/platform/measurement_utils.hpp b/platform/measurement_utils.hpp index 8006bd2fea..7c9752d388 100644 --- a/platform/measurement_utils.hpp +++ b/platform/measurement_utils.hpp @@ -26,12 +26,16 @@ inline std::string DebugPrint(Units units) inline double MetersToMiles(double m) { return m * 0.000621371192; } inline double MilesToMeters(double mi) { return mi * 1609.344; } +inline double MphToKmph(double mph) { return MilesToMeters(mph) / 1000.0; } +inline double KmphToMph(double kmph) { return MetersToMiles(kmph) * 1000.0; } inline double MetersToFeet(double m) { return m * 3.2808399; } inline double FeetToMeters(double ft) { return ft * 0.3048; } inline double FeetToMiles(double ft) { return ft * 5280; } inline double InchesToMeters(double in) { return in / 39.370; } inline double NauticalMilesToMeters(double nmi) { return nmi * 1852; } +double ToSpeedKmPH(double speed, measurement_utils::Units units); + /// Takes into an account user settings [metric, imperial] /// @param[in] m meters /// @param[out] res formatted std::string for search diff --git a/platform/platform_tests/measurement_tests.cpp b/platform/platform_tests/measurement_tests.cpp index 67beeef40f..41a449e22d 100644 --- a/platform/platform_tests/measurement_tests.cpp +++ b/platform/platform_tests/measurement_tests.cpp @@ -3,6 +3,8 @@ #include "platform/measurement_utils.hpp" #include "platform/settings.hpp" +#include "base/math.hpp" + #include "std/utility.hpp" using namespace measurement_utils; @@ -191,3 +193,16 @@ UNIT_TEST(OSMDistanceToMetersString) TEST_EQUAL(OSMDistanceToMetersString("15.123", false, 4), "15.123", ()); TEST_EQUAL(OSMDistanceToMetersString("15.654321", true, 1), "15.7", ()); } + +UNIT_TEST(ConversionUnits) +{ + double const kEps = 0.00001; + TEST(base::AlmostEqualAbs(MilesToMeters(MetersToMiles(1000.0)), 1000.0, kEps), ()); + TEST(base::AlmostEqualAbs(MilesToMeters(1.0), 1609.344, kEps), ()); + + TEST(base::AlmostEqualAbs(MphToKmph(KmphToMph(100.0)), 100.0, kEps), ()); + TEST(base::AlmostEqualAbs(MphToKmph(100.0), 160.934, kEps), ()); + + TEST(base::AlmostEqualAbs(ToSpeedKmPH(100.0, Units::Imperial), 160.934, kEps), ()); + TEST(base::AlmostEqualAbs(ToSpeedKmPH(100.0, Units::Metric), 100.0, kEps), ()); +} diff --git a/routing/CMakeLists.txt b/routing/CMakeLists.txt index 7566368333..10cf9b4f5b 100644 --- a/routing/CMakeLists.txt +++ b/routing/CMakeLists.txt @@ -63,6 +63,8 @@ set( joint_index.cpp joint_index.hpp loaded_path_segment.hpp + maxspeed_conversion.cpp + maxspeed_conversion.hpp maxspeed_serialization.cpp maxspeed_serialization.hpp nearest_edge_finder.cpp diff --git a/routing/maxspeed_conversion.cpp b/routing/maxspeed_conversion.cpp new file mode 100644 index 0000000000..119eff8546 --- /dev/null +++ b/routing/maxspeed_conversion.cpp @@ -0,0 +1,5 @@ +#include "routing/maxspeed_conversion.hpp" + +namespace routing +{ +} // namespace routing \ No newline at end of file diff --git a/routing/maxspeed_conversion.hpp b/routing/maxspeed_conversion.hpp new file mode 100644 index 0000000000..d7ffeeed78 --- /dev/null +++ b/routing/maxspeed_conversion.hpp @@ -0,0 +1,8 @@ +#pragma once + +#include + +namespace routing +{ + +} // namespace routing diff --git a/routing/routing_helpers.hpp b/routing/routing_helpers.hpp index e3f5cef722..a92dd79199 100644 --- a/routing/routing_helpers.hpp +++ b/routing/routing_helpers.hpp @@ -21,7 +21,6 @@ namespace routing { inline double KMPH2MPS(double kmph) { return kmph * 1000.0 / (60 * 60); } -inline double MilesPH2KMPH(double mph) { return mph / 0.621371192237334; } template bool IsCarRoad(Types const & types)