diff options
-rw-r--r-- | generator/feature_builder.cpp | 4 | ||||
-rw-r--r-- | generator/generator_tests/osm_type_test.cpp | 6 | ||||
-rw-r--r-- | routing/bicycle_model.cpp | 41 | ||||
-rw-r--r-- | routing/bicycle_model.hpp | 11 | ||||
-rw-r--r-- | routing/features_road_graph.cpp | 14 | ||||
-rw-r--r-- | routing/features_road_graph.hpp | 2 | ||||
-rw-r--r-- | routing/pedestrian_model.cpp | 20 | ||||
-rw-r--r-- | routing/pedestrian_model.hpp | 6 | ||||
-rw-r--r-- | routing/routing_tests/vehicle_model_test.cpp | 7 | ||||
-rw-r--r-- | routing/vehicle_model.cpp | 12 | ||||
-rw-r--r-- | routing/vehicle_model.hpp | 43 |
11 files changed, 117 insertions, 49 deletions
diff --git a/generator/feature_builder.cpp b/generator/feature_builder.cpp index b3f2faf0ca..e9814c380f 100644 --- a/generator/feature_builder.cpp +++ b/generator/feature_builder.cpp @@ -232,8 +232,8 @@ bool FeatureBuilder1::IsRoad() const { static routing::PedestrianModel const pedModel; static routing::BicycleModel const bicModel; - return routing::CarModel::Instance().IsRoad(m_params.m_Types) || pedModel.IsRoad(m_params.m_Types) - || bicModel.IsRoad(m_params.m_Types); + return routing::CarModel::Instance().HasRoadType(m_params.m_Types) || pedModel.HasRoadType(m_params.m_Types) + || bicModel.HasRoadType(m_params.m_Types); } bool FeatureBuilder1::PreSerialize() diff --git a/generator/generator_tests/osm_type_test.cpp b/generator/generator_tests/osm_type_test.cpp index 4a156d6730..9c3d7925a1 100644 --- a/generator/generator_tests/osm_type_test.cpp +++ b/generator/generator_tests/osm_type_test.cpp @@ -612,15 +612,15 @@ UNIT_TEST(OsmType_Ferry) uint32_t type = GetType({"highway", "primary", "bridge"}); TEST(params.IsTypeExist(type), ()); - TEST(carModel.IsRoad(type), ()); + TEST(carModel.IsRoadType(type), ()); type = GetType({"route", "ferry", "motorcar"}); TEST(params.IsTypeExist(type), ()); - TEST(carModel.IsRoad(type), ()); + TEST(carModel.IsRoadType(type), ()); type = GetType({"route", "ferry"}); TEST(!params.IsTypeExist(type), ()); - TEST(!carModel.IsRoad(type), ()); + TEST(!carModel.IsRoadType(type), ()); } UNIT_TEST(OsmType_Boundary) diff --git a/routing/bicycle_model.cpp b/routing/bicycle_model.cpp index 77cae657e1..962939377c 100644 --- a/routing/bicycle_model.cpp +++ b/routing/bicycle_model.cpp @@ -601,13 +601,15 @@ BicycleModel::BicycleModel(VehicleModel::InitListT const & speedLimits) void BicycleModel::Init() { - // @TODO(bykoianko) Uncomment line below what tags hwtag=nobicycle and hwtag=yesbicycle - // will be added to classificator.txt. (https://jira.mail.ru/browse/MAPSME-858) -// m_noBicycleType = classif().GetTypeByPath({ "hwtag", "nobicycle" }); -// m_yesBicycleType = classif().GetTypeByPath({ "hwtag", "yesbicycle" }); + initializer_list<char const *> hwtagYesbicycle = { "hwtag", "yesbicycle" }; + + m_yesBicycleType = classif().GetTypeByPath(hwtagYesbicycle); + m_noBicycleType = classif().GetTypeByPath({ "hwtag", "nobicycle" }); + m_bicycleBidirType = classif().GetTypeByPath({ "hwtag", "bicycle_bidir" }); initializer_list<char const *> arr[] = { + hwtagYesbicycle, { "route", "ferry" }, { "man_made", "pier" }, }; @@ -625,18 +627,45 @@ bool BicycleModel::IsYesBicycle(feature::TypesHolder const & types) const return find(types.begin(), types.end(), m_yesBicycleType) != types.end(); } +bool BicycleModel::IsBicycleBidir(feature::TypesHolder const & types) const +{ + return find(types.begin(), types.end(), m_bicycleBidirType) != types.end(); +} + double BicycleModel::GetSpeed(FeatureType const & f) const { feature::TypesHolder types(f); if (IsYesBicycle(types)) return VehicleModel::GetMaxSpeed(); - if (!IsNoBicycle(types) && IsRoad(types)) - return VehicleModel::GetSpeed(types); + if (!IsNoBicycle(types) && HasRoadType(types)) + return VehicleModel::GetMinTypeSpeed(types); return 0.0; } +bool BicycleModel::IsOneWay(FeatureType const & f) const +{ + feature::TypesHolder const types(f); + + if (IsBicycleBidir(types)) + return false; + + return VehicleModel::IsOneWay(f); +} + +bool BicycleModel::IsRoad(FeatureType const & f) const +{ + if (f.GetFeatureType() != feature::GEOM_LINE) + return false; + + feature::TypesHolder types(f); + + if (IsNoBicycle(types)) + return false; + return VehicleModel::HasRoadType(types); +} + BicycleModelFactory::BicycleModelFactory() { m_models[string()] = make_shared<BicycleModel>(g_bicycleLimitsDefault); diff --git a/routing/bicycle_model.hpp b/routing/bicycle_model.hpp index 2a7fdaa4fa..83875e6cbb 100644 --- a/routing/bicycle_model.hpp +++ b/routing/bicycle_model.hpp @@ -14,10 +14,10 @@ public: BicycleModel(); BicycleModel(VehicleModel::InitListT const & speedLimits); - /// @name Overrides from VehicleModel. - //@{ + /// VehicleModel overrides. double GetSpeed(FeatureType const & f) const override; - //@} + bool IsOneWay(FeatureType const & f) const override; + bool IsRoad(FeatureType const & f) const override; private: void Init(); @@ -30,8 +30,13 @@ private: /// but if function returns false, real allowance is unknown. bool IsYesBicycle(feature::TypesHolder const & types) const; + /// @return true if it is allowed to ride bicycle in two directions, + /// but if function returns false, real allowance is unknown. + bool IsBicycleBidir(feature::TypesHolder const & types) const; + uint32_t m_noBicycleType = 0; uint32_t m_yesBicycleType = 0; + uint32_t m_bicycleBidirType = 0; }; class BicycleModelFactory : public IVehicleModelFactory diff --git a/routing/features_road_graph.cpp b/routing/features_road_graph.cpp index f32794f4a6..6d8711a006 100644 --- a/routing/features_road_graph.cpp +++ b/routing/features_road_graph.cpp @@ -60,6 +60,11 @@ bool FeaturesRoadGraph::CrossCountryVehicleModel::IsOneWay(FeatureType const & f return GetVehicleModel(f.GetID())->IsOneWay(f); } +bool FeaturesRoadGraph::CrossCountryVehicleModel::IsRoad(FeatureType const & f) const +{ + return GetVehicleModel(f.GetID())->IsRoad(f); +} + IVehicleModel * FeaturesRoadGraph::CrossCountryVehicleModel::GetVehicleModel(FeatureID const & featureId) const { auto itr = m_cache.find(featureId.m_mwmId); @@ -114,7 +119,7 @@ public: void operator()(FeatureType & ft) { - if (ft.GetFeatureType() != feature::GEOM_LINE) + if (!m_graph.IsRoad(ft)) return; double const speedKMPH = m_graph.GetSpeedKMPHFromFt(ft); @@ -167,7 +172,7 @@ void FeaturesRoadGraph::FindClosestEdges(m2::PointD const & point, uint32_t coun auto const f = [&finder, this](FeatureType & ft) { - if (ft.GetFeatureType() != feature::GEOM_LINE) + if (!m_vehicleModel.IsRoad(ft)) return; double const speedKMPH = m_vehicleModel.GetSpeed(ft); @@ -236,6 +241,11 @@ void FeaturesRoadGraph::ClearState() m_mwmLocks.clear(); } +bool FeaturesRoadGraph::IsRoad(FeatureType const & ft) const +{ + return m_vehicleModel.IsRoad(ft); +} + bool FeaturesRoadGraph::IsOneWay(FeatureType const & ft) const { return m_vehicleModel.IsOneWay(ft); diff --git a/routing/features_road_graph.hpp b/routing/features_road_graph.hpp index af61afd11f..df3d7ec47a 100644 --- a/routing/features_road_graph.hpp +++ b/routing/features_road_graph.hpp @@ -31,6 +31,7 @@ private: double GetSpeed(FeatureType const & f) const override; double GetMaxSpeed() const override; bool IsOneWay(FeatureType const & f) const override; + bool IsRoad(FeatureType const & f) const override; void Clear(); @@ -77,6 +78,7 @@ public: private: friend class CrossFeaturesLoader; + bool IsRoad(FeatureType const & ft) const; bool IsOneWay(FeatureType const & ft) const; double GetSpeedKMPHFromFt(FeatureType const & ft) const; diff --git a/routing/pedestrian_model.cpp b/routing/pedestrian_model.cpp index af22fa59f3..e2a305a147 100644 --- a/routing/pedestrian_model.cpp +++ b/routing/pedestrian_model.cpp @@ -621,11 +621,14 @@ PedestrianModel::PedestrianModel(VehicleModel::InitListT const & speedLimits) void PedestrianModel::Init() { + initializer_list<char const *> hwtagYesfoot = { "hwtag", "yesfoot" }; + m_noFootType = classif().GetTypeByPath({ "hwtag", "nofoot" }); - m_yesFootType = classif().GetTypeByPath({ "hwtag", "yesfoot" }); + m_yesFootType = classif().GetTypeByPath(hwtagYesfoot); initializer_list<char const *> arr[] = { + hwtagYesfoot, { "route", "ferry" }, { "man_made", "pier" }, }; @@ -649,12 +652,23 @@ double PedestrianModel::GetSpeed(FeatureType const & f) const if (IsYesFoot(types)) return VehicleModel::GetMaxSpeed(); - if (!IsNoFoot(types) && IsRoad(types)) - return VehicleModel::GetSpeed(types); + if (!IsNoFoot(types) && HasRoadType(types)) + return VehicleModel::GetMinTypeSpeed(types); return 0.0; } +bool PedestrianModel::IsRoad(FeatureType const & f) const +{ + if (f.GetFeatureType() != feature::GEOM_LINE) + return false; + + feature::TypesHolder types(f); + + if (IsNoFoot(types)) + return false; + return VehicleModel::HasRoadType(types); +} PedestrianModelFactory::PedestrianModelFactory() { diff --git a/routing/pedestrian_model.hpp b/routing/pedestrian_model.hpp index b32db45e27..3369ed46be 100644 --- a/routing/pedestrian_model.hpp +++ b/routing/pedestrian_model.hpp @@ -14,11 +14,10 @@ public: PedestrianModel(); PedestrianModel(VehicleModel::InitListT const & speedLimits); - /// @name Overrides from VehicleModel. - //@{ + /// VehicleModel overrides. double GetSpeed(FeatureType const & f) const override; bool IsOneWay(FeatureType const &) const override { return false; } - //@} + bool IsRoad(FeatureType const & f) const override; private: void Init(); @@ -49,5 +48,4 @@ public: private: unordered_map<string, shared_ptr<IVehicleModel>> m_models; }; - } // namespace routing diff --git a/routing/routing_tests/vehicle_model_test.cpp b/routing/routing_tests/vehicle_model_test.cpp index 7f4bffe8fc..1215dbc5f6 100644 --- a/routing/routing_tests/vehicle_model_test.cpp +++ b/routing/routing_tests/vehicle_model_test.cpp @@ -21,6 +21,8 @@ routing::VehicleModel::InitListT const s_testLimits = { class TestVehicleModel : public routing::VehicleModel { + friend void CheckOneWay(initializer_list<uint32_t> const & types, bool expectedValue); + friend void CheckSpeed(initializer_list<uint32_t> const & types, double expectedSpeed); public: TestVehicleModel() : VehicleModel(classif(), s_testLimits) {} }; @@ -44,7 +46,7 @@ void CheckSpeed(initializer_list<uint32_t> const & types, double expectedSpeed) for (uint32_t t : types) h(t); - TEST_EQUAL(vehicleModel.GetSpeed(h), expectedSpeed, ()); + TEST_EQUAL(vehicleModel.GetMinTypeSpeed(h), expectedSpeed, ()); } void CheckOneWay(initializer_list<uint32_t> const & types, bool expectedValue) @@ -54,9 +56,8 @@ void CheckOneWay(initializer_list<uint32_t> const & types, bool expectedValue) for (uint32_t t : types) h(t); - TEST_EQUAL(vehicleModel.IsOneWay(h), expectedValue, ()); + TEST_EQUAL(vehicleModel.HasOneWayType(h), expectedValue, ()); } - } // namespace UNIT_TEST(VehicleModel_MaxSpeed) diff --git a/routing/vehicle_model.cpp b/routing/vehicle_model.cpp index 9f2cfe4412..d08faaef9b 100644 --- a/routing/vehicle_model.cpp +++ b/routing/vehicle_model.cpp @@ -32,10 +32,10 @@ void VehicleModel::SetAdditionalRoadTypes(Classificator const & c, double VehicleModel::GetSpeed(FeatureType const & f) const { - return GetSpeed(feature::TypesHolder(f)); + return GetMinTypeSpeed(feature::TypesHolder(f)); } -double VehicleModel::GetSpeed(feature::TypesHolder const & types) const +double VehicleModel::GetMinTypeSpeed(feature::TypesHolder const & types) const { double speed = m_maxSpeedKMpH * 2; for (uint32_t t : types) @@ -53,20 +53,20 @@ double VehicleModel::GetSpeed(feature::TypesHolder const & types) const bool VehicleModel::IsOneWay(FeatureType const & f) const { - return IsOneWay(feature::TypesHolder(f)); + return HasOneWayType(feature::TypesHolder(f)); } -bool VehicleModel::IsOneWay(feature::TypesHolder const & types) const +bool VehicleModel::HasOneWayType(feature::TypesHolder const & types) const { return types.Has(m_onewayType); } bool VehicleModel::IsRoad(FeatureType const & f) const { - return (f.GetFeatureType() == feature::GEOM_LINE) && IsRoad(feature::TypesHolder(f)); + return (f.GetFeatureType() == feature::GEOM_LINE) && HasRoadType(feature::TypesHolder(f)); } -bool VehicleModel::IsRoad(uint32_t type) const +bool VehicleModel::IsRoadType(uint32_t type) const { return find(m_addRoadTypes.begin(), m_addRoadTypes.end(), type) != m_addRoadTypes.end() || m_types.find(ftypes::BaseChecker::PrepareToMatch(type, 2)) != m_types.end(); diff --git a/routing/vehicle_model.hpp b/routing/vehicle_model.hpp index dbd1ef5205..f01427838b 100644 --- a/routing/vehicle_model.hpp +++ b/routing/vehicle_model.hpp @@ -29,6 +29,10 @@ public: virtual double GetMaxSpeed() const = 0; virtual bool IsOneWay(FeatureType const & f) const = 0; + + /// @returns true if feature |f| can be used for routing with corresponding vehicle model + /// and returns false otherwise. + virtual bool IsRoad(FeatureType const & f) const = 0; }; class IVehicleModelFactory @@ -56,37 +60,42 @@ public: VehicleModel(Classificator const & c, InitListT const & speedLimits); - /// @name Overrides from IVehicleModel. - //@{ + /// IVehicleModel overrides. double GetSpeed(FeatureType const & f) const override; double GetMaxSpeed() const override { return m_maxSpeedKMpH; } bool IsOneWay(FeatureType const & f) const override; - //@} - - double GetSpeed(feature::TypesHolder const & types) const; - - /// \returns true if |types| is a oneway feature. - /// \note According to OSM tag "oneway" could have value "-1". That means it's a oneway feature - /// with reversed geometry. In that case while map generation the geometry of such features - /// is reversed (the order of points is changed) so in vehicle model all oneway feature - /// could be considered as features with forward geometry. - bool IsOneWay(feature::TypesHolder const & types) const; - - bool IsRoad(FeatureType const & f) const; - template <class TList> bool IsRoad(TList const & types) const + /// @note If VehicleModel::IsRoad() returns true for a feature its implementation in + /// inherited class may return true or false. + /// If VehicleModel::IsRoad() returns false for a feature its implementation in + /// inherited class must return false as well. + bool IsRoad(FeatureType const & f) const override; + + /// @returns true if |m_types| or |m_addRoadTypes| contains |type| and false otherwise. + /// @note The set of |types| IsRoadType method returns true for should contain any set of feature types + /// IsRoad method (and its implementation in inherited classes) returns true for. + bool IsRoadType(uint32_t type) const; + template <class TList> bool HasRoadType(TList const & types) const { for (uint32_t t : types) - if (IsRoad(t)) + if (IsRoadType(t)) return true; return false; } - bool IsRoad(uint32_t type) const; protected: /// Used in derived class constructors only. Not for public use. void SetAdditionalRoadTypes(Classificator const & c, initializer_list<char const *> const * arr, size_t sz); + /// \returns true if |types| is a oneway feature. + /// \note According to OSM tag "oneway" could have value "-1". That means it's a oneway feature + /// with reversed geometry. In that case while map generation the geometry of such features + /// is reversed (the order of points is changed) so in vehicle model all oneway feature + /// could be considered as features with forward geometry. + bool HasOneWayType(feature::TypesHolder const & types) const; + + double GetMinTypeSpeed(feature::TypesHolder const & types) const; + double m_maxSpeedKMpH; private: |