diff --git a/data/classificator.txt b/data/classificator.txt index 3430a97f98..bfd34ec274 100644 --- a/data/classificator.txt +++ b/data/classificator.txt @@ -634,7 +634,9 @@ world + {} {} route + - ferry - + ferry + + motorcar - + {} {} shop + alcohol - diff --git a/data/drules_proto.txt b/data/drules_proto.txt index a4937b7897..aaf4afb87a 100644 --- a/data/drules_proto.txt +++ b/data/drules_proto.txt @@ -56947,6 +56947,149 @@ cont { } } } +cont { + name: "route-ferry-motorcar" + element { + scale: 10 + lines { + width: 1.0 + color: 10075118 + dashdot { + dd: 3.0 + dd: 2.0 + } + priority: 1174 + join: ROUNDJOIN + cap: BUTTCAP + } + } + element { + scale: 11 + lines { + width: 1.0 + color: 10075118 + dashdot { + dd: 3.0 + dd: 2.0 + } + priority: 1174 + join: ROUNDJOIN + cap: BUTTCAP + } + } + element { + scale: 12 + lines { + width: 1.0 + color: 10075118 + dashdot { + dd: 3.0 + dd: 2.0 + } + priority: 1375 + join: ROUNDJOIN + cap: BUTTCAP + } + } + element { + scale: 13 + lines { + width: 1.0 + color: 10075118 + dashdot { + dd: 3.0 + dd: 2.0 + } + priority: 1411 + join: ROUNDJOIN + cap: BUTTCAP + } + } + element { + scale: 14 + lines { + width: 1.0 + color: 10075118 + dashdot { + dd: 3.0 + dd: 2.0 + } + priority: 1474 + join: ROUNDJOIN + cap: BUTTCAP + } + } + element { + scale: 15 + lines { + width: 1.0 + color: 10075118 + dashdot { + dd: 7.0 + dd: 5.0 + } + priority: 1648 + join: ROUNDJOIN + cap: BUTTCAP + } + } + element { + scale: 16 + lines { + width: 2.0 + color: 11193565 + dashdot { + dd: 12.0 + dd: 8.0 + } + priority: 1834 + join: ROUNDJOIN + cap: BUTTCAP + } + } + element { + scale: 17 + lines { + width: 2.0 + color: 11193565 + dashdot { + dd: 12.0 + dd: 8.0 + } + priority: 1924 + join: ROUNDJOIN + cap: BUTTCAP + } + } + element { + scale: 18 + lines { + width: 2.0 + color: 11193565 + dashdot { + dd: 12.0 + dd: 8.0 + } + priority: 1924 + join: ROUNDJOIN + cap: BUTTCAP + } + } + element { + scale: 19 + lines { + width: 2.0 + color: 11193565 + dashdot { + dd: 12.0 + dd: 8.0 + } + priority: 1924 + join: ROUNDJOIN + cap: BUTTCAP + } + } +} cont { name: "shop" element { diff --git a/data/mapcss-mapping.csv b/data/mapcss-mapping.csv index 663dc88cdc..8aaed673ee 100644 --- a/data/mapcss-mapping.csv +++ b/data/mapcss-mapping.csv @@ -986,3 +986,4 @@ internet_access|wlan;[internet_access=wlan];;name;int_name;985; amenity|waste_disposal;[amenity=waste_disposal];;name;int_name;986; amenity|bbq;[amenity=bbq];;name;int_name;987; hwtag|private;[hwtag=private];;name;int_name;988; +route|ferry|motorcar;[route=ferry];;name;int_name;989; diff --git a/data/types.txt b/data/types.txt index f96c774859..fb12837dab 100644 --- a/data/types.txt +++ b/data/types.txt @@ -986,3 +986,4 @@ internet_access|wlan amenity|waste_disposal amenity|bbq hwtag|private +route|ferry|motorcar diff --git a/generator/feature_builder.cpp b/generator/feature_builder.cpp index 1d1574e5a9..9621967d21 100644 --- a/generator/feature_builder.cpp +++ b/generator/feature_builder.cpp @@ -1,5 +1,7 @@ #include "feature_builder.hpp" +#include "../routing/vehicle_model.hpp" + #include "../indexer/feature_impl.hpp" #include "../indexer/feature_visibility.hpp" #include "../indexer/geometry_serialization.hpp" @@ -175,13 +177,10 @@ namespace } } -bool FeatureBuilder1::IsHighway() const +bool FeatureBuilder1::IsRoad() const { - /// @todo Add additional type for check "route-ferry-motorcar" - /// when it will be added as separate type into classificator. - - static feature::TypeSetChecker const checkHighway("highway"); - return checkHighway.IsEqualV(m_params.m_Types); + static routing::CarModel const carModel; + return carModel.IsRoad(m_params.m_Types); } bool FeatureBuilder1::PreSerialize() @@ -212,7 +211,7 @@ bool FeatureBuilder1::PreSerialize() case GEOM_LINE: { // We need refs for road's numbers. - if (!IsHighway()) + if (!IsRoad()) m_params.ref.clear(); m_params.rank = 0; @@ -621,7 +620,7 @@ void FeatureBuilder2::Serialize(buffers_holder_t & data, serial::CodingParams co uint64_t FeatureBuilder2::GetWayIDForRouting() const { - if (m_osmIds.size() == 1 && m_osmIds[0].IsWay() && IsLine() && IsHighway()) + if (m_osmIds.size() == 1 && m_osmIds[0].IsWay() && IsLine() && IsRoad()) return m_osmIds[0].OsmId(); else return 0; diff --git a/generator/feature_builder.hpp b/generator/feature_builder.hpp index b3fa6b329f..8b061b8b09 100644 --- a/generator/feature_builder.hpp +++ b/generator/feature_builder.hpp @@ -168,7 +168,7 @@ public: bool CheckValid() const; //@} - bool IsHighway() const; + bool IsRoad() const; protected: /// Used for features debugging diff --git a/generator/feature_sorter.cpp b/generator/feature_sorter.cpp index b23d03ba76..eda3cdaf78 100644 --- a/generator/feature_sorter.cpp +++ b/generator/feature_sorter.cpp @@ -452,7 +452,7 @@ namespace feature points_t points; // Do not change linear geometry for the upper scale. - if (isLine && i == scalesStart && IsCountry() && fb.IsHighway()) + if (isLine && i == scalesStart && IsCountry() && fb.IsRoad()) points = holder.GetSourcePoints(); else SimplifyPoints(holder.GetSourcePoints(), points, level, isCoast, rect); diff --git a/generator/generator_tests/generator_tests.pro b/generator/generator_tests/generator_tests.pro index c6b6e94d4c..57e9e07601 100644 --- a/generator/generator_tests/generator_tests.pro +++ b/generator/generator_tests/generator_tests.pro @@ -4,7 +4,7 @@ CONFIG -= app_bundle TEMPLATE = app ROOT_DIR = ../.. -DEPENDENCIES = map generator indexer platform geometry coding base expat sgitess protobuf tomcrypt osrm +DEPENDENCIES = generator map routing indexer platform geometry coding base expat sgitess protobuf tomcrypt osrm include($$ROOT_DIR/common.pri) diff --git a/generator/generator_tests/osm_type_test.cpp b/generator/generator_tests/osm_type_test.cpp index 9a441591fa..fd3f19281a 100644 --- a/generator/generator_tests/osm_type_test.cpp +++ b/generator/generator_tests/osm_type_test.cpp @@ -3,6 +3,8 @@ #include "../xml_element.hpp" #include "../osm2type.hpp" +#include "../../routing/vehicle_model.hpp" + #include "../../indexer/feature_data.hpp" #include "../../indexer/classificator.hpp" #include "../../indexer/classificator_loader.hpp" @@ -537,3 +539,38 @@ UNIT_TEST(OsmType_Hwtag) TEST(params.IsTypeExist(GetType(tags[1])), ()); } } + +UNIT_TEST(OsmType_Ferry) +{ + routing::CarModel carModel; + + char const * arr[][2] = { + { "motorcar", "yes" }, + { "highway", "primary" }, + { "bridge", "yes" }, + { "route", "ferry" }, + }; + + XMLElement e; + FillXmlElement(arr, ARRAY_SIZE(arr), &e); + + FeatureParams params; + ftype::GetNameAndType(&e, params); + + TEST_EQUAL(params.m_Types.size(), 2, (params)); + + char const * type1[] = { "highway", "primary", "bridge" }; + uint32_t type = GetType(type1); + TEST(params.IsTypeExist(type), ()); + TEST(carModel.IsRoad(type), ()); + + char const * type2[] = { "route", "ferry", "motorcar" }; + type = GetType(type2); + TEST(params.IsTypeExist(type), ()); + TEST(carModel.IsRoad(type), ()); + + char const * type3[] = { "route", "ferry" }; + type = GetType(type3); + TEST(!params.IsTypeExist(type), ()); + TEST(!carModel.IsRoad(type), ()); +} diff --git a/indexer/ftypes_matcher.cpp b/indexer/ftypes_matcher.cpp index e254dbcac0..bdee45d5c6 100644 --- a/indexer/ftypes_matcher.cpp +++ b/indexer/ftypes_matcher.cpp @@ -8,16 +8,15 @@ namespace ftypes { -uint32_t BaseChecker::PrepareFeatureTypeToMatch(uint32_t featureType) +uint32_t BaseChecker::PrepareToMatch(uint32_t type) { - ftype::TruncValue(featureType, 2); - return featureType; + ftype::TruncValue(type, 2); + return type; } -bool BaseChecker::IsMatched(uint32_t t) const +bool BaseChecker::IsMatched(uint32_t type) const { - ftype::TruncValue(t, 2); - return (find(m_types.begin(), m_types.end(), t) != m_types.end()); + return (find(m_types.begin(), m_types.end(), PrepareToMatch(type)) != m_types.end()); } bool BaseChecker::operator() (feature::TypesHolder const & types) const diff --git a/indexer/ftypes_matcher.hpp b/indexer/ftypes_matcher.hpp index 8215f8f36e..b1bbf10363 100644 --- a/indexer/ftypes_matcher.hpp +++ b/indexer/ftypes_matcher.hpp @@ -13,7 +13,7 @@ namespace ftypes class BaseChecker { - bool IsMatched(uint32_t t) const; + bool IsMatched(uint32_t type) const; protected: vector m_types; @@ -23,7 +23,7 @@ public: bool operator() (FeatureType const & ft) const; bool operator() (vector const & types) const; - static uint32_t PrepareFeatureTypeToMatch(uint32_t featureType); + static uint32_t PrepareToMatch(uint32_t type); }; class IsStreetChecker : public BaseChecker diff --git a/routing/osrm_router.cpp b/routing/osrm_router.cpp index 46d9b238a4..8a3b140cd6 100644 --- a/routing/osrm_router.cpp +++ b/routing/osrm_router.cpp @@ -27,8 +27,6 @@ class Point2PhantomNode m2::PointD m_point; OsrmFtSegMapping const & m_mapping; - CarModel m_carModel; - struct Candidate { double m_dist; @@ -49,7 +47,8 @@ public: void operator() (FeatureType const & ft) { - if (ft.GetFeatureType() != feature::GEOM_LINE || m_carModel.GetSpeed(ft) == 0) + static CarModel const carModel; + if (ft.GetFeatureType() != feature::GEOM_LINE || !carModel.IsRoad(ft)) return; Candidate res; diff --git a/routing/vehicle_model.cpp b/routing/vehicle_model.cpp index 798746afa8..4ef0bed5f6 100644 --- a/routing/vehicle_model.cpp +++ b/routing/vehicle_model.cpp @@ -42,8 +42,13 @@ CarModel::CarModel() VehicleModel::VehicleModel(Classificator const & c, vector const & speedLimits) : m_maxSpeed(0) { - char const * arr[] = { "hwtag", "oneway" }; - m_onewayType = c.GetTypeByPath(vector(arr, arr + 2)); + { + char const * arr2[] = { "hwtag", "oneway" }; + m_onewayType = c.GetTypeByPath(vector(arr2, arr2 + 2)); + + char const * arr3[] = { "route", "ferry", "motorcar" }; + m_ferryType = c.GetTypeByPath(vector(arr3, arr3 + 3)); + } for (size_t i = 0; i < speedLimits.size(); ++i) { @@ -62,7 +67,7 @@ double VehicleModel::GetSpeed(feature::TypesHolder const & types) const double speed = m_maxSpeed * 2; for (size_t i = 0; i < types.Size(); ++i) { - uint32_t const type = ftypes::BaseChecker::PrepareFeatureTypeToMatch(types[i]); + uint32_t const type = ftypes::BaseChecker::PrepareToMatch(types[i]); TypesT::const_iterator it = m_types.find(type); if (it != m_types.end()) speed = min(speed, it->second.m_speed); @@ -83,4 +88,27 @@ bool VehicleModel::IsOneWay(feature::TypesHolder const & types) const return types.Has(m_onewayType); } +bool VehicleModel::IsRoad(FeatureType const & f) const +{ + feature::TypesHolder types(f); + for (size_t i = 0; i < types.Size(); ++i) + if (IsRoad(types[i])) + return true; + return false; +} + +bool VehicleModel::IsRoad(vector const & types) const +{ + for (uint32_t t : types) + if (IsRoad(t)) + return true; + return false; +} + +bool VehicleModel::IsRoad(uint32_t type) const +{ + return (type == m_ferryType || + m_types.find(ftypes::BaseChecker::PrepareToMatch(type)) != m_types.end()); +} + } diff --git a/routing/vehicle_model.hpp b/routing/vehicle_model.hpp index 2a7303c8af..78e40eb371 100644 --- a/routing/vehicle_model.hpp +++ b/routing/vehicle_model.hpp @@ -4,6 +4,7 @@ #include "../std/vector.hpp" #include "../std/stdint.hpp" + class Classificator; class FeatureType; @@ -40,11 +41,17 @@ public: double GetSpeed(feature::TypesHolder const & types) const; bool IsOneWay(feature::TypesHolder const & types) const; + bool IsRoad(FeatureType const & f) const; + bool IsRoad(vector const & types) const; + bool IsRoad(uint32_t type) const; + private: double m_maxSpeed; + typedef unordered_map TypesT; TypesT m_types; - uint32_t m_onewayType; + + uint32_t m_onewayType, m_ferryType; }; class CarModel : public VehicleModel