diff --git a/generator/generator_tool/generator_tool.cpp b/generator/generator_tool/generator_tool.cpp index af28f73d58..3a83d7eb90 100644 --- a/generator/generator_tool/generator_tool.cpp +++ b/generator/generator_tool/generator_tool.cpp @@ -28,12 +28,19 @@ #include "indexer/map_style_reader.hpp" #include "indexer/rank_table.hpp" +#include "storage/country_parent_getter.hpp" + #include "platform/platform.hpp" #include "coding/file_name_utils.hpp" #include "base/timer.hpp" +#include "std/unique_ptr.hpp" + +#include +#include + #include "defines.hpp" #include "3party/gflags/src/gflags/gflags.h" @@ -175,6 +182,14 @@ int main(int argc, char ** argv) classif().SortClassificator(); } + // Load mwm tree only if we need it + std::unique_ptr countryParentGetter; + if (FLAGS_make_routing_index || FLAGS_make_cross_mwm) + { + countryParentGetter = + make_unique(); + } + // Generate dat file. if (FLAGS_generate_features || FLAGS_make_coasts) { @@ -269,6 +284,14 @@ int main(int argc, char ** argv) if (FLAGS_make_routing_index) { + if (!countryParentGetter) + { + // All the mwms should use proper VehicleModels. + LOG(LCRITICAL, ("Countries file is needed. Please set countries file name (countries.txt or " + "countries_obsolete.txt). File must be located in data directory.")); + return -1; + } + std::string const restrictionsFilename = genInfo.GetIntermediateFileName(RESTRICTIONS_FILENAME, "" /* extension */); std::string const roadAccessFilename = @@ -276,13 +299,21 @@ int main(int argc, char ** argv) routing::BuildRoadRestrictions(datFile, restrictionsFilename, osmToFeatureFilename); routing::BuildRoadAccessInfo(datFile, roadAccessFilename, osmToFeatureFilename); - routing::BuildRoutingIndex(datFile, country); + routing::BuildRoutingIndex(datFile, country, *countryParentGetter); } if (FLAGS_make_cross_mwm) { - if (!routing::BuildCrossMwmSection(path, datFile, country, osmToFeatureFilename, - FLAGS_disable_cross_mwm_progress)) + if (!countryParentGetter) + { + // All the mwms should use proper VehicleModels. + LOG(LCRITICAL, ("Countries file is needed. Please set countries file name (countries.txt or " + "countries_obsolete.txt). File must be located in data directory.")); + return -1; + } + + if (!routing::BuildCrossMwmSection(path, datFile, country, *countryParentGetter, + osmToFeatureFilename, FLAGS_disable_cross_mwm_progress)) LOG(LCRITICAL, ("Error generating cross mwm section.")); } diff --git a/generator/generator_tool/generator_tool.pro b/generator/generator_tool/generator_tool.pro index 41fa8a943b..e1addd5838 100644 --- a/generator/generator_tool/generator_tool.pro +++ b/generator/generator_tool/generator_tool.pro @@ -18,6 +18,10 @@ TEMPLATE = app # needed for Platform::WorkingDir() and unicode combining QT *= core +!iphone*:!android*:!tizen:!macx-* { + QT *= network +} + macx-* { LIBS *= "-framework IOKit" "-framework SystemConfiguration" } diff --git a/generator/routing_index_generator.cpp b/generator/routing_index_generator.cpp index 77a66cfea2..82ce22dde1 100644 --- a/generator/routing_index_generator.cpp +++ b/generator/routing_index_generator.cpp @@ -30,7 +30,9 @@ #include "base/logging.hpp" #include +#include #include +#include #include #include #include @@ -45,10 +47,13 @@ namespace class VehicleMaskBuilder final { public: - explicit VehicleMaskBuilder(string const & country) - : m_pedestrianModel(PedestrianModelFactory().GetVehicleModelForCountry(country)) - , m_bicycleModel(BicycleModelFactory().GetVehicleModelForCountry(country)) - , m_carModel(CarModelFactory().GetVehicleModelForCountry(country)) + VehicleMaskBuilder(string const & country, + CountryParentNameGetterFn const & countryParentNameGetterFn) + : m_pedestrianModel( + PedestrianModelFactory(countryParentNameGetterFn).GetVehicleModelForCountry(country)) + , m_bicycleModel( + BicycleModelFactory(countryParentNameGetterFn).GetVehicleModelForCountry(country)) + , m_carModel(CarModelFactory(countryParentNameGetterFn).GetVehicleModelForCountry(country)) { CHECK(m_pedestrianModel, ()); CHECK(m_bicycleModel, ()); @@ -58,13 +63,13 @@ public: VehicleMask CalcRoadMask(FeatureType const & f) const { return CalcMask( - f, [&](IVehicleModel const & model, FeatureType const & f) { return model.IsRoad(f); }); + f, [&](VehicleModelInterface const & model, FeatureType const & f) { return model.IsRoad(f); }); } VehicleMask CalcOneWayMask(FeatureType const & f) const { return CalcMask( - f, [&](IVehicleModel const & model, FeatureType const & f) { return model.IsOneWay(f); }); + f, [&](VehicleModelInterface const & model, FeatureType const & f) { return model.IsOneWay(f); }); } private: @@ -82,15 +87,18 @@ private: return mask; } - shared_ptr const m_pedestrianModel; - shared_ptr const m_bicycleModel; - shared_ptr const m_carModel; + shared_ptr const m_pedestrianModel; + shared_ptr const m_bicycleModel; + shared_ptr const m_carModel; }; class Processor final { public: - explicit Processor(string const & country) : m_maskBuilder(country) {} + Processor(string const & country, CountryParentNameGetterFn const & countryParentNameGetterFn) + : m_maskBuilder(country, countryParentNameGetterFn) + { + } void ProcessAllFeatures(string const & filename) { @@ -200,6 +208,7 @@ RouteWeight CalcDistanceAlongTheBorders(vector const & borders, } void CalcCrossMwmTransitions(string const & path, string const & mwmFile, string const & country, + CountryParentNameGetterFn const & countryParentNameGetterFn, map const & featureIdToOsmId, vector & transitions, CrossMwmConnectorPerVehicleType & connectors) @@ -209,7 +218,7 @@ void CalcCrossMwmTransitions(string const & path, string const & mwmFile, string vector borders; osm::LoadBorders(polyFile, borders); - VehicleMaskBuilder const maskMaker(country); + VehicleMaskBuilder const maskMaker(country, countryParentNameGetterFn); feature::ForEachFromDat(mwmFile, [&](FeatureType const & f, uint32_t featureId) { VehicleMask const roadMask = maskMaker.CalcRoadMask(f); @@ -266,11 +275,13 @@ void CalcCrossMwmTransitions(string const & path, string const & mwmFile, string } void FillWeights(string const & path, string const & mwmFile, string const & country, + CountryParentNameGetterFn const & countryParentNameGetterFn, bool disableCrossMwmProgress, CrossMwmConnector & connector) { my::Timer timer; - shared_ptr vehicleModel = CarModelFactory().GetVehicleModelForCountry(country); + shared_ptr vehicleModel = + CarModelFactory(countryParentNameGetterFn).GetVehicleModelForCountry(country); IndexGraph graph(GeometryLoader::CreateFromFile(mwmFile, vehicleModel), EdgeEstimator::Create(VehicleType::Car, vehicleModel->GetMaxSpeed(), nullptr /* trafficStash */)); @@ -335,12 +346,13 @@ serial::CodingParams LoadCodingParams(string const & mwmFile) namespace routing { -bool BuildRoutingIndex(string const & filename, string const & country) +bool BuildRoutingIndex(string const & filename, string const & country, + CountryParentNameGetterFn const & countryParentNameGetterFn) { LOG(LINFO, ("Building routing index for", filename)); try { - Processor processor(country); + Processor processor(country, countryParentNameGetterFn); processor.ProcessAllFeatures(filename); IndexGraph graph; @@ -365,6 +377,7 @@ bool BuildRoutingIndex(string const & filename, string const & country) } bool BuildCrossMwmSection(string const & path, string const & mwmFile, string const & country, + CountryParentNameGetterFn const & countryParentNameGetterFn, string const & osmToFeatureFile, bool disableCrossMwmProgress) { LOG(LINFO, ("Building cross mwm section for", country)); @@ -376,7 +389,8 @@ bool BuildCrossMwmSection(string const & path, string const & mwmFile, string co CrossMwmConnectorPerVehicleType connectors; vector transitions; - CalcCrossMwmTransitions(path, mwmFile, country, featureIdToOsmId, transitions, connectors); + CalcCrossMwmTransitions(path, mwmFile, country, countryParentNameGetterFn, featureIdToOsmId, + transitions, connectors); for (size_t i = 0; i < connectors.size(); ++i) { @@ -386,7 +400,7 @@ bool BuildCrossMwmSection(string const & path, string const & mwmFile, string co connector.GetExits().size())); } - FillWeights(path, mwmFile, country, disableCrossMwmProgress, + FillWeights(path, mwmFile, country, countryParentNameGetterFn, disableCrossMwmProgress, connectors[static_cast(VehicleType::Car)]); serial::CodingParams const codingParams = LoadCodingParams(mwmFile); diff --git a/generator/routing_index_generator.hpp b/generator/routing_index_generator.hpp index 4f58eb8e2e..a56de1f066 100644 --- a/generator/routing_index_generator.hpp +++ b/generator/routing_index_generator.hpp @@ -1,12 +1,17 @@ #pragma once #include +#include #include namespace routing { -bool BuildRoutingIndex(std::string const & filename, std::string const & country); +using CountryParentNameGetterFn = std::function; + +bool BuildRoutingIndex(std::string const & filename, std::string const & country, + CountryParentNameGetterFn const & countryParentNameGetterFn); bool BuildCrossMwmSection(std::string const & path, std::string const & mwmFile, - std::string const & country, std::string const & osmToFeatureFile, - bool disableCrossMwmProgress); + std::string const & country, + CountryParentNameGetterFn const & countryParentNameGetterFn, + std::string const & osmToFeatureFile, bool disableCrossMwmProgress); } // namespace routing diff --git a/map/framework.cpp b/map/framework.cpp index 87adbe3efa..1f483f860e 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -96,7 +96,6 @@ #include "std/bind.hpp" #include "std/target_os.hpp" #include "std/utility.hpp" -#include "std/vector.hpp" #include "api/internal/c/api-client-internals.h" #include "api/src/c/api-client.h" @@ -391,13 +390,16 @@ Framework::Framework(FrameworkParams const & params) , m_bmManager(*this) , m_isRenderingEnabled(true) , m_routingManager(RoutingManager::Callbacks([this]() -> Index & { return m_model.GetIndex(); }, - std::bind(&Framework::GetCountryInfoGetter, this)), + [this]() -> storage::CountryInfoGetter & { return GetCountryInfoGetter(); }, + [this](string const & id) -> string { + return m_storage.GetParentIdFor(id); + }), static_cast(*this)) - , m_trafficManager(std::bind(&Framework::GetMwmsByRect, this, _1, false /* rough */), + , m_trafficManager(bind(&Framework::GetMwmsByRect, this, _1, false /* rough */), kMaxTrafficCacheSizeBytes, m_routingManager.RoutingSession()) - , m_localAdsManager(std::bind(&Framework::GetMwmsByRect, this, _1, true /* rough */), - std::bind(&Framework::GetMwmIdByName, this, _1), - std::bind(&Framework::ReadFeatures, this, _1, _2)) + , m_localAdsManager(bind(&Framework::GetMwmsByRect, this, _1, true /* rough */), + bind(&Framework::GetMwmIdByName, this, _1), + bind(&Framework::ReadFeatures, this, _1, _2)) , m_displacementModeManager([this](bool show) { int const mode = show ? dp::displacement::kHotelMode : dp::displacement::kDefaultMode; if (m_drapeEngine != nullptr) @@ -409,7 +411,7 @@ Framework::Framework(FrameworkParams const & params) // Restore map style before classificator loading MapStyle mapStyle = kDefaultMapStyle; - std::string mapStyleStr; + string mapStyleStr; if (settings::Get(kMapStyleKey, mapStyleStr)) mapStyle = MapStyleFromSettings(mapStyleStr); GetStyleReader().SetCurrentStyle(mapStyle); @@ -1503,7 +1505,7 @@ void Framework::InitTransliteration() try { ZipFileReader::UnzipFile(GetPlatform().ResourcesDir(), - std::string("assets/") + kICUDataFile, + string("assets/") + kICUDataFile, GetPlatform().WritableDir() + kICUDataFile); } catch (RootException const & e) @@ -1564,7 +1566,7 @@ search::DisplayedCategories const & Framework::GetDisplayedCategories() ASSERT(m_cityFinder, ()); ms::LatLon latlon; - std::string city; + string city; if (GetCurrentPosition(latlon.lat, latlon.lon)) { @@ -1894,12 +1896,12 @@ void Framework::CreateDrapeEngine(ref_ptr contextFactory, }); }; - auto overlaysShowStatsFn = [this](std::list && events) + auto overlaysShowStatsFn = [this](list && events) { if (events.empty()) return; - std::list statEvents; + list statEvents; for (auto const & event : events) { auto const & mwmInfo = event.m_feature.m_mwmId.GetInfo(); @@ -2090,7 +2092,7 @@ void Framework::MarkMapStyle(MapStyle mapStyle) ASSERT_NOT_EQUAL(mapStyle, MapStyle::MapStyleMerged, ()); // Store current map style before classificator reloading - std::string mapStyleStr = MapStyleToString(mapStyle); + string mapStyleStr = MapStyleToString(mapStyle); if (mapStyleStr.empty()) { mapStyle = kDefaultMapStyle; @@ -2374,7 +2376,7 @@ void Framework::InvalidateUserMarks() { m_bmManager.InitBookmarks(); - std::vector const types = {UserMarkType::SEARCH_MARK, UserMarkType::API_MARK, + vector const types = {UserMarkType::SEARCH_MARK, UserMarkType::API_MARK, UserMarkType::DEBUG_MARK, UserMarkType::ROUTING_MARK, UserMarkType::LOCAL_ADS_MARK}; for (size_t typeIndex = 0; typeIndex < types.size(); typeIndex++) @@ -2744,9 +2746,9 @@ void Framework::EnableChoosePositionMode(bool enable, bool enableBounds, bool ap applyPosition, position); } -std::vector Framework::GetSelectedFeatureTriangles() const +vector Framework::GetSelectedFeatureTriangles() const { - std::vector triangles; + vector triangles; if (!m_selectedFeature.IsValid()) return triangles; @@ -2798,7 +2800,7 @@ uint32_t GetBestType(FeatureType const & ft) } } -bool Framework::ParseDrapeDebugCommand(std::string const & query) +bool Framework::ParseDrapeDebugCommand(string const & query) { MapStyle desiredStyle = MapStyleCount; if (query == "?dark" || query == "mapstyle:dark") @@ -3325,15 +3327,15 @@ vector Framework::GetMwmsByRect(m2::RectD const & rect, bool roug return result; } -MwmSet::MwmId Framework::GetMwmIdByName(std::string const & name) const +MwmSet::MwmId Framework::GetMwmIdByName(string const & name) const { return m_model.GetIndex().GetMwmIdByCountryFile(platform::CountryFile(name)); } -void Framework::ReadFeatures(std::function const & reader, - std::set const & features) +void Framework::ReadFeatures(function const & reader, + set const & features) { - m_model.ReadFeatures(reader, std::vector(features.begin(), features.end())); + m_model.ReadFeatures(reader, vector(features.begin(), features.end())); } // RoutingManager::Delegate @@ -3359,7 +3361,7 @@ void Framework::OnRouteFollow(routing::RouterType type) } // RoutingManager::Delegate -void Framework::RegisterCountryFilesOnRoute(std::shared_ptr ptr) const +void Framework::RegisterCountryFilesOnRoute(shared_ptr ptr) const { m_storage.ForEachCountryFile( [&ptr](platform::CountryFile const & file) { ptr->RegisterFile(file); }); diff --git a/map/framework.hpp b/map/framework.hpp index 1be36f1ac4..6fc6be2709 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -65,7 +65,11 @@ #include "base/strings_bundle.hpp" #include "base/thread_checker.hpp" +#include "std/function.hpp" #include "std/list.hpp" +#include "std/set.hpp" +#include "std/shared_ptr.hpp" +#include "std/string.hpp" #include "std/target_os.hpp" #include "std/unique_ptr.hpp" #include "std/vector.hpp" @@ -382,10 +386,10 @@ public: void SetCurrentCountryChangedListener(TCurrentCountryChanged const & listener); vector GetMwmsByRect(m2::RectD const & rect, bool rough) const; - MwmSet::MwmId GetMwmIdByName(std::string const & name) const; + MwmSet::MwmId GetMwmIdByName(string const & name) const; - void ReadFeatures(std::function const & reader, - std::set const & features); + void ReadFeatures(function const & reader, + set const & features); private: struct TapEvent @@ -431,7 +435,7 @@ private: vector m_searchMarksSizes; private: - std::vector GetSelectedFeatureTriangles() const; + vector GetSelectedFeatureTriangles() const; public: @@ -657,7 +661,7 @@ private: /// @returns true if command was handled by editor. bool ParseEditorDebugCommand(search::SearchParams const & params); /// @returns true if command was handled by drape. - bool ParseDrapeDebugCommand(std::string const & query); + bool ParseDrapeDebugCommand(string const & query); void FillFeatureInfo(FeatureID const & fid, place_page::Info & info) const; /// @param customTitle, if not empty, overrides any other calculated name. @@ -770,7 +774,7 @@ public: protected: /// RoutingManager::Delegate void OnRouteFollow(routing::RouterType type) override; - void RegisterCountryFilesOnRoute(std::shared_ptr ptr) const override; + void RegisterCountryFilesOnRoute(shared_ptr ptr) const override; public: /// @name Editor interface. diff --git a/map/routing_manager.cpp b/map/routing_manager.cpp index 3dad8e26d0..e85dec2dcb 100644 --- a/map/routing_manager.cpp +++ b/map/routing_manager.cpp @@ -389,8 +389,10 @@ void RoutingManager::SetRouterImpl(RouterType type) }; auto fetcher = make_unique(countryFileGetter, localFileChecker); - auto router = make_unique(vehicleType, countryFileGetter, getMwmRectByName, numMwmIds, - MakeNumMwmTree(*numMwmIds, m_callbacks.m_countryInfoGetter()), m_routingSession, index); + auto router = make_unique(vehicleType, m_callbacks.m_countryParentNameGetterFn, + countryFileGetter, getMwmRectByName, numMwmIds, + MakeNumMwmTree(*numMwmIds, m_callbacks.m_countryInfoGetter()), + m_routingSession, index); m_routingSession.SetRoutingSettings(GetRoutingSettings(vehicleType)); m_routingSession.SetRouter(move(router), move(fetcher)); diff --git a/map/routing_manager.hpp b/map/routing_manager.hpp index ce29756235..2a1a171fd4 100644 --- a/map/routing_manager.hpp +++ b/map/routing_manager.hpp @@ -68,14 +68,19 @@ public: { using IndexGetterFn = std::function; using CountryInfoGetterFn = std::function; + using CountryParentNameGetterFn = std::function; - Callbacks(IndexGetterFn && featureIndexGetter, CountryInfoGetterFn && countryInfoGetter) - : m_indexGetter(std::move(featureIndexGetter)) - , m_countryInfoGetter(std::move(countryInfoGetter)) + template + Callbacks(IndexGetter && featureIndexGetter, CountryInfoGetter && countryInfoGetter, + CountryParentNameGetter && countryParentNameGetter) + : m_indexGetter(std::forward(featureIndexGetter)) + , m_countryInfoGetter(std::forward(countryInfoGetter)) + , m_countryParentNameGetterFn(std::forward(countryParentNameGetter)) {} IndexGetterFn m_indexGetter; CountryInfoGetterFn m_countryInfoGetter; + CountryParentNameGetterFn m_countryParentNameGetterFn; }; using RouteBuildingCallback = diff --git a/openlr/openlr_simple_decoder.cpp b/openlr/openlr_simple_decoder.cpp index c1bd14c863..31747060c5 100644 --- a/openlr/openlr_simple_decoder.cpp +++ b/openlr/openlr_simple_decoder.cpp @@ -77,7 +77,11 @@ bool OpenLRSimpleDecoder::SegmentsFilter::Matches(LinearSegment const & segment) } // OpenLRSimpleDecoder ----------------------------------------------------------------------------- -OpenLRSimpleDecoder::OpenLRSimpleDecoder(vector const & indexes) : m_indexes(indexes) {} +OpenLRSimpleDecoder::OpenLRSimpleDecoder( + vector const & indexes, CountryParentNameGetterFn const & countryParentNameGetterFn) + : m_indexes(indexes), m_countryParentNameGetterFn(countryParentNameGetterFn) +{ +} void OpenLRSimpleDecoder::Decode(std::vector const & segments, uint32_t const numThreads, std::vector & paths) @@ -95,7 +99,7 @@ void OpenLRSimpleDecoder::Decode(std::vector const & segments, auto worker = [&segments, &paths, kBatchSize, kProgressFrequency, kOffsetToleranceM, numThreads, this](size_t threadNum, Index const & index, Stats & stats) { FeaturesRoadGraph roadGraph(index, IRoadGraph::Mode::ObeyOnewayTag, - make_unique()); + make_unique(m_countryParentNameGetterFn)); RoadInfoGetter roadInfoGetter(index); Router router(roadGraph, roadInfoGetter); diff --git a/openlr/openlr_simple_decoder.hpp b/openlr/openlr_simple_decoder.hpp index 82911ddd02..c15c13dced 100644 --- a/openlr/openlr_simple_decoder.hpp +++ b/openlr/openlr_simple_decoder.hpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -21,6 +22,8 @@ DECLARE_EXCEPTION(DecoderError, RootException); class OpenLRSimpleDecoder { public: + using CountryParentNameGetterFn = std::function; + class SegmentsFilter { public: @@ -34,7 +37,8 @@ public: bool const m_multipointsOnly; }; - OpenLRSimpleDecoder(std::vector const & indexes); + OpenLRSimpleDecoder(std::vector const & indexes, + CountryParentNameGetterFn const & countryParentNameGetterFn); // Maps partner segments to mwm paths. |segments| should be sorted by partner id. void Decode(std::vector const & segments, uint32_t const numThreads, @@ -42,5 +46,6 @@ public: private: std::vector const & m_indexes; + CountryParentNameGetterFn m_countryParentNameGetterFn; }; } // namespace openlr diff --git a/openlr/openlr_stat/CMakeLists.txt b/openlr/openlr_stat/CMakeLists.txt index 025c605919..ae709edbf0 100644 --- a/openlr/openlr_stat/CMakeLists.txt +++ b/openlr/openlr_stat/CMakeLists.txt @@ -12,6 +12,7 @@ omim_link_libraries(${PROJECT_NAME} openlr routing routing_common + storage indexer editor platform diff --git a/openlr/openlr_stat/openlr_stat.cpp b/openlr/openlr_stat/openlr_stat.cpp index 14dd131afa..b2a914da9c 100644 --- a/openlr/openlr_stat/openlr_stat.cpp +++ b/openlr/openlr_stat/openlr_stat.cpp @@ -5,6 +5,8 @@ #include "indexer/classificator_loader.hpp" #include "indexer/index.hpp" +#include "storage/country_parent_getter.hpp" + #include "platform/local_country_file.hpp" #include "platform/local_country_file_utils.hpp" #include "platform/platform.hpp" @@ -20,6 +22,8 @@ #include "3party/gflags/src/gflags/gflags.h" #include "3party/pugixml/src/pugixml.hpp" +#include "std/unique_ptr.hpp" + #include #include #include @@ -39,6 +43,9 @@ DEFINE_int32(limit, -1, "Max number of segments to handle. -1 for all."); DEFINE_bool(multipoints_only, false, "Only segments with multiple points to handle."); DEFINE_int32(num_threads, 1, "Number of threads."); DEFINE_string(ids_path, "", "Path to a file with segment ids to process."); +DEFINE_string(countries_filename, "", + "Name of countries file which describes mwm tree. Used to get country specific " + "routing restrictions."); using namespace openlr; @@ -214,7 +221,8 @@ int main(int argc, char * argv[]) std::vector indexes(numThreads); LoadIndexes(FLAGS_mwms_path, indexes); - OpenLRSimpleDecoder decoder(indexes); + OpenLRSimpleDecoder decoder(indexes, storage::CountryParentGetter(FLAGS_countries_filename, + GetPlatform().ResourcesDir())); pugi::xml_document document; auto const load_result = document.load_file(FLAGS_input.data()); diff --git a/openlr/openlr_stat/openlr_stat.pro b/openlr/openlr_stat/openlr_stat.pro index 0e7255b792..0864469c6d 100644 --- a/openlr/openlr_stat/openlr_stat.pro +++ b/openlr/openlr_stat/openlr_stat.pro @@ -16,6 +16,10 @@ TEMPLATE = app # needed for Platform::WorkingDir() and unicode combining QT *= core +!iphone*:!android*:!tizen:!macx-* { + QT *= network +} + macx-* { LIBS *= "-framework IOKit" "-framework SystemConfiguration" } diff --git a/routing/cross_mwm_graph.cpp b/routing/cross_mwm_graph.cpp index 56507269bd..2248d156fa 100644 --- a/routing/cross_mwm_graph.cpp +++ b/routing/cross_mwm_graph.cpp @@ -44,8 +44,9 @@ void CrossMwmGraph::ClosestSegment::Update(double distM, Segment const & bestSeg } // CrossMwmGraph ---------------------------------------------------------------------------------- -CrossMwmGraph::CrossMwmGraph(shared_ptr numMwmIds, shared_ptr> numMwmTree, - shared_ptr vehicleModelFactory, +CrossMwmGraph::CrossMwmGraph(shared_ptr numMwmIds, + shared_ptr> numMwmTree, + shared_ptr vehicleModelFactory, CourntryRectFn const & countryRectFn, Index & index, RoutingIndexManager & indexManager) : m_index(index) diff --git a/routing/cross_mwm_graph.hpp b/routing/cross_mwm_graph.hpp index cb7deea232..5ce27ac6fd 100644 --- a/routing/cross_mwm_graph.hpp +++ b/routing/cross_mwm_graph.hpp @@ -33,7 +33,7 @@ public: }; CrossMwmGraph(std::shared_ptr numMwmIds, shared_ptr> numMwmTree, - std::shared_ptr vehicleModelFactory, + std::shared_ptr vehicleModelFactory, CourntryRectFn const & countryRectFn, Index & index, RoutingIndexManager & indexManager); @@ -151,7 +151,7 @@ private: Index & m_index; std::shared_ptr m_numMwmIds; std::shared_ptr> m_numMwmTree; - std::shared_ptr m_vehicleModelFactory; + std::shared_ptr m_vehicleModelFactory; CourntryRectFn const & m_countryRectFn; CrossMwmIndexGraph m_crossMwmIndexGraph; CrossMwmOsrmGraph m_crossMwmOsrmGraph; diff --git a/routing/features_road_graph.cpp b/routing/features_road_graph.cpp index c2d368ef02..7a7392f948 100644 --- a/routing/features_road_graph.cpp +++ b/routing/features_road_graph.cpp @@ -25,18 +25,6 @@ double constexpr kMwmRoadCrossingRadiusMeters = 2.0; double constexpr kMwmCrossingNodeEqualityRadiusMeters = 100.0; -string GetFeatureCountryName(FeatureID const featureId) -{ - /// @todo Rework this function when storage will provide information about mwm's country - // MwmInfo.GetCountryName returns country name as 'Country' or 'Country_Region', but only 'Country' is needed - ASSERT(featureId.IsValid(), ()); - - string const & countryName = featureId.m_mwmId.GetInfo()->GetCountryName(); - size_t const pos = countryName.find('_'); - if (string::npos == pos) - return countryName; - return countryName.substr(0, pos); -} } // namespace FeaturesRoadGraph::Value::Value(MwmSet::MwmHandle handle) : m_mwmHandle(move(handle)) @@ -48,7 +36,7 @@ FeaturesRoadGraph::Value::Value(MwmSet::MwmHandle handle) : m_mwmHandle(move(han } FeaturesRoadGraph::CrossCountryVehicleModel::CrossCountryVehicleModel( - shared_ptr vehicleModelFactory) + shared_ptr vehicleModelFactory) : m_vehicleModelFactory(vehicleModelFactory) , m_maxSpeedKMPH(m_vehicleModelFactory->GetVehicleModel()->GetMaxSpeed()) { @@ -79,14 +67,14 @@ bool FeaturesRoadGraph::CrossCountryVehicleModel::IsTransitAllowed(FeatureType c return GetVehicleModel(f.GetID())->IsTransitAllowed(f); } -IVehicleModel * FeaturesRoadGraph::CrossCountryVehicleModel::GetVehicleModel(FeatureID const & featureId) const +VehicleModelInterface * FeaturesRoadGraph::CrossCountryVehicleModel::GetVehicleModel(FeatureID const & featureId) const { auto itr = m_cache.find(featureId.m_mwmId); if (itr != m_cache.end()) return itr->second.get(); - string const country = GetFeatureCountryName(featureId); - auto const vehicleModel = m_vehicleModelFactory->GetVehicleModelForCountry(country); + auto const vehicleModel = m_vehicleModelFactory->GetVehicleModelForCountry( + featureId.m_mwmId.GetInfo()->GetCountryName()); ASSERT(nullptr != vehicleModel, ()); ASSERT_EQUAL(m_maxSpeedKMPH, vehicleModel->GetMaxSpeed(), ()); @@ -114,7 +102,7 @@ void FeaturesRoadGraph::RoadInfoCache::Clear() m_cache.clear(); } FeaturesRoadGraph::FeaturesRoadGraph(Index const & index, IRoadGraph::Mode mode, - shared_ptr vehicleModelFactory) + shared_ptr vehicleModelFactory) : m_index(index), m_mode(mode), m_vehicleModel(vehicleModelFactory) { } diff --git a/routing/features_road_graph.hpp b/routing/features_road_graph.hpp index e0303e9c8d..d44a6d9c77 100644 --- a/routing/features_road_graph.hpp +++ b/routing/features_road_graph.hpp @@ -25,12 +25,12 @@ namespace routing class FeaturesRoadGraph : public IRoadGraph { private: - class CrossCountryVehicleModel : public IVehicleModel + class CrossCountryVehicleModel : public VehicleModelInterface { public: - CrossCountryVehicleModel(shared_ptr vehicleModelFactory); + CrossCountryVehicleModel(shared_ptr vehicleModelFactory); - // IVehicleModel overrides: + // VehicleModelInterface overrides: double GetSpeed(FeatureType const & f) const override; double GetMaxSpeed() const override; bool IsOneWay(FeatureType const & f) const override; @@ -40,12 +40,12 @@ private: void Clear(); private: - IVehicleModel * GetVehicleModel(FeatureID const & featureId) const; + VehicleModelInterface * GetVehicleModel(FeatureID const & featureId) const; - shared_ptr const m_vehicleModelFactory; + shared_ptr const m_vehicleModelFactory; double const m_maxSpeedKMPH; - mutable map> m_cache; + mutable map> m_cache; }; class RoadInfoCache @@ -62,7 +62,7 @@ private: public: FeaturesRoadGraph(Index const & index, IRoadGraph::Mode mode, - shared_ptr vehicleModelFactory); + shared_ptr vehicleModelFactory); static int GetStreetReadScale(); diff --git a/routing/geometry.cpp b/routing/geometry.cpp index d990ed6454..a40d92ad42 100644 --- a/routing/geometry.cpp +++ b/routing/geometry.cpp @@ -20,13 +20,13 @@ class GeometryLoaderImpl final : public GeometryLoader { public: GeometryLoaderImpl(Index const & index, MwmSet::MwmHandle const & handle, - shared_ptr vehicleModel, bool loadAltitudes); + shared_ptr vehicleModel, bool loadAltitudes); // GeometryLoader overrides: void Load(uint32_t featureId, RoadGeometry & road) override; private: - shared_ptr m_vehicleModel; + shared_ptr m_vehicleModel; Index::FeaturesLoaderGuard m_guard; string const m_country; feature::AltitudeLoader m_altitudeLoader; @@ -34,7 +34,7 @@ private: }; GeometryLoaderImpl::GeometryLoaderImpl(Index const & index, MwmSet::MwmHandle const & handle, - shared_ptr vehicleModel, bool loadAltitudes) + shared_ptr vehicleModel, bool loadAltitudes) : m_vehicleModel(move(vehicleModel)) , m_guard(index, handle.GetId()) , m_country(handle.GetInfo()->GetCountryName()) @@ -66,18 +66,18 @@ void GeometryLoaderImpl::Load(uint32_t featureId, RoadGeometry & road) class FileGeometryLoader final : public GeometryLoader { public: - FileGeometryLoader(string const & fileName, shared_ptr vehicleModel); + FileGeometryLoader(string const & fileName, shared_ptr vehicleModel); // GeometryLoader overrides: void Load(uint32_t featureId, RoadGeometry & road) override; private: FeaturesVectorTest m_featuresVector; - shared_ptr m_vehicleModel; + shared_ptr m_vehicleModel; }; FileGeometryLoader::FileGeometryLoader(string const & fileName, - shared_ptr vehicleModel) + shared_ptr vehicleModel) : m_featuresVector(FilesContainerR(make_unique(fileName))) , m_vehicleModel(vehicleModel) { @@ -106,7 +106,7 @@ RoadGeometry::RoadGeometry(bool oneWay, double speed, Points const & points) m_junctions.emplace_back(point, feature::kDefaultAltitudeMeters); } -void RoadGeometry::Load(IVehicleModel const & vehicleModel, FeatureType const & feature, +void RoadGeometry::Load(VehicleModelInterface const & vehicleModel, FeatureType const & feature, feature::TAltitudes const * altitudes) { CHECK(altitudes == nullptr || altitudes->size() == feature.GetPointsCount(), ()); @@ -156,7 +156,7 @@ RoadGeometry const & Geometry::GetRoad(uint32_t featureId) // static unique_ptr GeometryLoader::Create(Index const & index, MwmSet::MwmHandle const & handle, - shared_ptr vehicleModel, + shared_ptr vehicleModel, bool loadAltitudes) { CHECK(handle.IsAlive(), ()); @@ -165,7 +165,7 @@ unique_ptr GeometryLoader::Create(Index const & index, // static unique_ptr GeometryLoader::CreateFromFile(string const & fileName, - shared_ptr vehicleModel) + shared_ptr vehicleModel) { return make_unique(fileName, vehicleModel); } diff --git a/routing/geometry.hpp b/routing/geometry.hpp index aca2078279..aa432b27dd 100644 --- a/routing/geometry.hpp +++ b/routing/geometry.hpp @@ -27,7 +27,7 @@ public: RoadGeometry() = default; RoadGeometry(bool oneWay, double speed, Points const & points); - void Load(IVehicleModel const & vehicleModel, FeatureType const & feature, + void Load(VehicleModelInterface const & vehicleModel, FeatureType const & feature, feature::TAltitudes const * altitudes); bool IsOneWay() const { return m_isOneWay; } @@ -75,13 +75,13 @@ public: // handle should be alive: it is caller responsibility to check it. static std::unique_ptr Create(Index const & index, MwmSet::MwmHandle const & handle, - std::shared_ptr vehicleModel, + std::shared_ptr vehicleModel, bool loadAltitudes); /// This is for stand-alone work. /// Use in generator_tool and unit tests. static std::unique_ptr CreateFromFile( - std::string const & fileName, std::shared_ptr vehicleModel); + std::string const & fileName, std::shared_ptr vehicleModel); }; class Geometry final diff --git a/routing/index_graph_loader.cpp b/routing/index_graph_loader.cpp index 98d12d6f8f..e50fd1832e 100644 --- a/routing/index_graph_loader.cpp +++ b/routing/index_graph_loader.cpp @@ -19,7 +19,7 @@ class IndexGraphLoaderImpl final : public IndexGraphLoader { public: IndexGraphLoaderImpl(VehicleType vehicleType, shared_ptr numMwmIds, - shared_ptr vehicleModelFactory, + shared_ptr vehicleModelFactory, shared_ptr estimator, Index & index); // IndexGraphLoader overrides: @@ -32,13 +32,13 @@ private: VehicleMask m_vehicleMask; Index & m_index; shared_ptr m_numMwmIds; - shared_ptr m_vehicleModelFactory; + shared_ptr m_vehicleModelFactory; shared_ptr m_estimator; unordered_map> m_graphs; }; IndexGraphLoaderImpl::IndexGraphLoaderImpl(VehicleType vehicleType, shared_ptr numMwmIds, - shared_ptr vehicleModelFactory, + shared_ptr vehicleModelFactory, shared_ptr estimator, Index & index) : m_vehicleMask(GetVehicleMask(vehicleType)) , m_index(index) @@ -67,7 +67,7 @@ IndexGraph & IndexGraphLoaderImpl::Load(NumMwmId numMwmId) if (!handle.IsAlive()) MYTHROW(RoutingException, ("Can't get mwm handle for", file)); - shared_ptr vehicleModel = + shared_ptr vehicleModel = m_vehicleModelFactory->GetVehicleModelForCountry(file.GetName()); auto graphPtr = make_unique( @@ -112,7 +112,7 @@ namespace routing // static unique_ptr IndexGraphLoader::Create( VehicleType vehicleType, shared_ptr numMwmIds, - shared_ptr vehicleModelFactory, shared_ptr estimator, + shared_ptr vehicleModelFactory, shared_ptr estimator, Index & index) { return make_unique(vehicleType, numMwmIds, vehicleModelFactory, estimator, diff --git a/routing/index_graph_loader.hpp b/routing/index_graph_loader.hpp index b1ba9c5de5..b286a40b61 100644 --- a/routing/index_graph_loader.hpp +++ b/routing/index_graph_loader.hpp @@ -23,7 +23,7 @@ public: static std::unique_ptr Create( VehicleType vehicleType, std::shared_ptr numMwmIds, - std::shared_ptr vehicleModelFactory, + std::shared_ptr vehicleModelFactory, std::shared_ptr estimator, Index & index); }; diff --git a/routing/index_router.cpp b/routing/index_router.cpp index ebbb7dfb53..d139076812 100644 --- a/routing/index_router.cpp +++ b/routing/index_router.cpp @@ -51,7 +51,7 @@ double constexpr kMinDistanceToFinishM = 10000; // Limit of adjust in seconds. double constexpr kAdjustLimitSec = 5 * 60; -double CalcMaxSpeed(NumMwmIds const & numMwmIds, VehicleModelFactory const & vehicleModelFactory) +double CalcMaxSpeed(NumMwmIds const & numMwmIds, VehicleModelFactoryInterface const & vehicleModelFactory) { double maxSpeed = 0.0; numMwmIds.ForEachId([&](NumMwmId id) { @@ -64,15 +64,17 @@ double CalcMaxSpeed(NumMwmIds const & numMwmIds, VehicleModelFactory const & veh return maxSpeed; } -shared_ptr CreateVehicleModelFactory(VehicleType vehicleType) +shared_ptr CreateVehicleModelFactory( + VehicleType vehicleType, CountryParentNameGetterFn const & countryParentNameGetterFn) { switch (vehicleType) { - case VehicleType::Pedestrian: return make_shared(); - case VehicleType::Bicycle: return make_shared(); - case VehicleType::Car: return make_shared(); + case VehicleType::Pedestrian: + return make_shared(countryParentNameGetterFn); + case VehicleType::Bicycle: return make_shared(countryParentNameGetterFn); + case VehicleType::Car: return make_shared(countryParentNameGetterFn); case VehicleType::Count: - CHECK(false, ("Can't create VehicleModelFactory for", vehicleType)); + CHECK(false, ("Can't create VehicleModelFactoryInterface for", vehicleType)); return nullptr; } } @@ -283,14 +285,14 @@ double IndexRouter::BestEdgeComparator::GetSquaredDist(Edge const & edge) const } // IndexRouter ------------------------------------------------------------------------------------ -IndexRouter::IndexRouter(VehicleType vehicleType, TCountryFileFn const & countryFileFn, - CourntryRectFn const & countryRectFn, shared_ptr numMwmIds, - unique_ptr> numMwmTree, traffic::TrafficCache const & trafficCache, - Index & index) +IndexRouter::IndexRouter(VehicleType vehicleType, CountryParentNameGetterFn const & countryParentNameGetterFn, + TCountryFileFn const & countryFileFn, CourntryRectFn const & countryRectFn, + shared_ptr numMwmIds, unique_ptr> numMwmTree, + traffic::TrafficCache const & trafficCache, Index & index) : m_vehicleType(vehicleType) , m_name("astar-bidirectional-" + ToString(m_vehicleType)) , m_index(index) - , m_vehicleModelFactory(CreateVehicleModelFactory(m_vehicleType)) + , m_vehicleModelFactory(CreateVehicleModelFactory(m_vehicleType, countryParentNameGetterFn)) , m_countryFileFn(countryFileFn) , m_countryRectFn(countryRectFn) , m_numMwmIds(move(numMwmIds)) diff --git a/routing/index_router.hpp b/routing/index_router.hpp index 471955aa80..91d58795f9 100644 --- a/routing/index_router.hpp +++ b/routing/index_router.hpp @@ -55,8 +55,10 @@ public: m2::PointD const m_direction; }; - IndexRouter(VehicleType vehicleType, TCountryFileFn const & countryFileFn, CourntryRectFn const & countryRectFn, - shared_ptr numMwmIds, unique_ptr> numMwmTree, traffic::TrafficCache const & trafficCache, Index & index); + IndexRouter(VehicleType vehicleType, CountryParentNameGetterFn const & countryParentNameGetterFn, + TCountryFileFn const & countryFileFn, CourntryRectFn const & countryRectFn, + shared_ptr numMwmIds, unique_ptr> numMwmTree, + traffic::TrafficCache const & trafficCache, Index & index); // IRouter overrides: std::string GetName() const override { return m_name; } @@ -105,7 +107,7 @@ private: VehicleType m_vehicleType; std::string const m_name; Index & m_index; - std::shared_ptr m_vehicleModelFactory; + std::shared_ptr m_vehicleModelFactory; TCountryFileFn const m_countryFileFn; CourntryRectFn const m_countryRectFn; diff --git a/routing/road_graph_router.cpp b/routing/road_graph_router.cpp index f72dd3507a..28366ab4fa 100644 --- a/routing/road_graph_router.cpp +++ b/routing/road_graph_router.cpp @@ -116,7 +116,7 @@ void FindClosestEdges(IRoadGraph const & graph, m2::PointD const & point, RoadGraphRouter::~RoadGraphRouter() {} RoadGraphRouter::RoadGraphRouter(string const & name, Index const & index, TCountryFileFn const & countryFileFn, IRoadGraph::Mode mode, - unique_ptr && vehicleModelFactory, + unique_ptr && vehicleModelFactory, unique_ptr && algorithm, unique_ptr && directionsEngine) : m_name(name) @@ -236,7 +236,7 @@ unique_ptr CreatePedestrianAStarRouter(Index & index, TCountryFileFn const & countryFileFn, shared_ptr numMwmIds) { - unique_ptr vehicleModelFactory(new PedestrianModelFactory()); + unique_ptr vehicleModelFactory(new PedestrianModelFactory()); unique_ptr algorithm(new AStarRoutingAlgorithm()); unique_ptr directionsEngine( new PedestrianDirectionsEngine(std::move(numMwmIds))); @@ -250,7 +250,7 @@ unique_ptr CreatePedestrianAStarBidirectionalRouter(Index & index, TCountryFileFn const & countryFileFn, shared_ptr numMwmIds) { - unique_ptr vehicleModelFactory(new PedestrianModelFactory()); + unique_ptr vehicleModelFactory(new PedestrianModelFactory()); unique_ptr algorithm(new AStarBidirectionalRoutingAlgorithm()); unique_ptr directionsEngine( new PedestrianDirectionsEngine(std::move(numMwmIds))); @@ -264,7 +264,7 @@ unique_ptr CreateBicycleAStarBidirectionalRouter(Index & index, TCountryFileFn const & countryFileFn, shared_ptr numMwmIds) { - unique_ptr vehicleModelFactory(new BicycleModelFactory()); + unique_ptr vehicleModelFactory(new BicycleModelFactory()); unique_ptr algorithm(new AStarBidirectionalRoutingAlgorithm()); unique_ptr directionsEngine( new BicycleDirectionsEngine(index, numMwmIds)); diff --git a/routing/road_graph_router.hpp b/routing/road_graph_router.hpp index cfb59e38e3..d97d3da004 100644 --- a/routing/road_graph_router.hpp +++ b/routing/road_graph_router.hpp @@ -26,7 +26,7 @@ class RoadGraphRouter : public IRouter { public: RoadGraphRouter(string const & name, Index const & index, TCountryFileFn const & countryFileFn, - IRoadGraph::Mode mode, unique_ptr && vehicleModelFactory, + IRoadGraph::Mode mode, unique_ptr && vehicleModelFactory, unique_ptr && algorithm, unique_ptr && directionsEngine); ~RoadGraphRouter() override; diff --git a/routing/router.hpp b/routing/router.hpp index 729585e827..d1a30670ee 100644 --- a/routing/router.hpp +++ b/routing/router.hpp @@ -17,6 +17,7 @@ namespace routing using TCountryFileFn = std::function; using CourntryRectFn = std::function; +using CountryParentNameGetterFn = std::function; class Route; diff --git a/routing/routing_benchmarks/bicycle_routing_tests.cpp b/routing/routing_benchmarks/bicycle_routing_tests.cpp index da006dd8f2..f7d09bac20 100644 --- a/routing/routing_benchmarks/bicycle_routing_tests.cpp +++ b/routing/routing_benchmarks/bicycle_routing_tests.cpp @@ -33,9 +33,9 @@ protected: return engine; } - unique_ptr CreateModelFactory() override + unique_ptr CreateModelFactory() override { - unique_ptr factory( + unique_ptr factory( new SimplifiedModelFactory()); return factory; } diff --git a/routing/routing_benchmarks/helpers.hpp b/routing/routing_benchmarks/helpers.hpp index b449dd5915..292fe25ce1 100644 --- a/routing/routing_benchmarks/helpers.hpp +++ b/routing/routing_benchmarks/helpers.hpp @@ -33,7 +33,7 @@ public: protected: virtual unique_ptr CreateDirectionsEngine( shared_ptr numMwmIds) = 0; - virtual unique_ptr CreateModelFactory() = 0; + virtual unique_ptr CreateModelFactory() = 0; template unique_ptr CreateRouter(string const & name) @@ -57,7 +57,7 @@ protected: }; template -class SimplifiedModelFactory : public routing::VehicleModelFactory +class SimplifiedModelFactory : public routing::VehicleModelFactoryInterface { public: // Since for test purposes we compare routes lengths to check @@ -66,7 +66,7 @@ public: class SimplifiedModel : public Model { public: - // IVehicleModel overrides: + // VehicleModelInterface overrides: // // SimplifiedModel::GetSpeed() filters features and returns zero // speed if feature is not allowed by the base model, or otherwise @@ -83,9 +83,10 @@ public: }; SimplifiedModelFactory() : m_model(make_shared()) {} - // VehicleModelFactory overrides: - shared_ptr GetVehicleModel() const override { return m_model; } - shared_ptr GetVehicleModelForCountry( + + // VehicleModelFactoryInterface overrides: + shared_ptr GetVehicleModel() const override { return m_model; } + shared_ptr GetVehicleModelForCountry( string const & /*country*/) const override { return m_model; diff --git a/routing/routing_benchmarks/pedestrian_routing_tests.cpp b/routing/routing_benchmarks/pedestrian_routing_tests.cpp index 4a98dedd06..ed92bb9979 100644 --- a/routing/routing_benchmarks/pedestrian_routing_tests.cpp +++ b/routing/routing_benchmarks/pedestrian_routing_tests.cpp @@ -50,9 +50,9 @@ protected: return engine; } - unique_ptr CreateModelFactory() override + unique_ptr CreateModelFactory() override { - unique_ptr factory( + unique_ptr factory( new SimplifiedModelFactory()); return factory; } diff --git a/routing/routing_integration_tests/routing_test_tools.cpp b/routing/routing_integration_tests/routing_test_tools.cpp index a271b43536..037370423c 100644 --- a/routing/routing_integration_tests/routing_test_tools.cpp +++ b/routing/routing_integration_tests/routing_test_tools.cpp @@ -26,6 +26,7 @@ #include "geometry/distance_on_sphere.hpp" +#include "std/functional.hpp" #include "std/limits.hpp" #include "private.h" @@ -102,8 +103,9 @@ namespace integration } auto vehicleType = VehicleType::Car; - auto indexRouter = make_unique(vehicleType, countryFileGetter, getMwmRectByName, numMwmIds, - MakeNumMwmTree(*numMwmIds, infoGetter), trafficCache, index); + auto indexRouter = make_unique(vehicleType, CountryParentNameGetterFn(), countryFileGetter, + getMwmRectByName, numMwmIds, + MakeNumMwmTree(*numMwmIds, infoGetter), trafficCache, index); return indexRouter; } diff --git a/routing/routing_tests/index_graph_tools.cpp b/routing/routing_tests/index_graph_tools.cpp index ef898a6a9f..c50e080f45 100644 --- a/routing/routing_tests/index_graph_tools.cpp +++ b/routing/routing_tests/index_graph_tools.cpp @@ -266,8 +266,8 @@ shared_ptr CreateEstimatorForCar(traffic::TrafficCache const & tr shared_ptr CreateEstimatorForCar(shared_ptr trafficStash) { - return EdgeEstimator::Create(VehicleType::Car, CarModelFactory().GetVehicleModel()->GetMaxSpeed(), - trafficStash); + return EdgeEstimator::Create(VehicleType::Car, + CarModelFactory({}).GetVehicleModel()->GetMaxSpeed(), trafficStash); } AStarAlgorithm::Result CalculateRoute(IndexGraphStarter & starter, diff --git a/routing_common/bicycle_model.cpp b/routing_common/bicycle_model.cpp index 00e9a43273..dc9a4591b3 100644 --- a/routing_common/bicycle_model.cpp +++ b/routing_common/bicycle_model.cpp @@ -420,14 +420,7 @@ VehicleModel::InitListT const g_bicycleLimitsUS = namespace routing { - -// If one of feature types will be disabled for bicycles, features of this type will be simplyfied -// in generator. Look FeatureBuilder1::IsRoad() for more details. -BicycleModel::BicycleModel() - : VehicleModel(classif(), g_bicycleLimitsAll) -{ - Init(); -} +BicycleModel::BicycleModel() : VehicleModel(classif(), g_bicycleLimitsDefault) { Init(); } BicycleModel::BicycleModel(VehicleModel::InitListT const & speedLimits) : VehicleModel(classif(), speedLimits) @@ -452,7 +445,7 @@ void BicycleModel::Init() SetAdditionalRoadTypes(classif(), additionalTags); } -IVehicleModel::RoadAvailability BicycleModel::GetRoadAvailability(feature::TypesHolder const & types) const +VehicleModelInterface::RoadAvailability BicycleModel::GetRoadAvailability(feature::TypesHolder const & types) const { if (types.Has(m_yesBicycleType)) return RoadAvailability::Available; @@ -476,14 +469,18 @@ bool BicycleModel::IsOneWay(FeatureType const & f) const return VehicleModel::IsOneWay(f); } +// If one of feature types will be disabled for bicycles, features of this type will be simplyfied +// in generator. Look FeatureBuilder1::IsRoad() for more details. // static BicycleModel const & BicycleModel::AllLimitsInstance() { - static BicycleModel const instance; + static BicycleModel const instance(g_bicycleLimitsAll); return instance; } -BicycleModelFactory::BicycleModelFactory() +BicycleModelFactory::BicycleModelFactory( + CountryParentNameGetterFn const & countryParentNameGetterFn) + : VehicleModelFactory(countryParentNameGetterFn) { // Names must be the same with country names from countries.txt m_models[""] = make_shared(g_bicycleLimitsDefault); @@ -513,22 +510,4 @@ BicycleModelFactory::BicycleModelFactory() m_models["United States of America"] = make_shared(g_bicycleLimitsUS); } -shared_ptr BicycleModelFactory::GetVehicleModel() const -{ - auto const itr = m_models.find(""); - ASSERT(itr != m_models.end(), ()); - return itr->second; -} - -shared_ptr BicycleModelFactory::GetVehicleModelForCountry(string const & country) const -{ - auto const itr = m_models.find(country); - if (itr != m_models.end()) - { - LOG(LDEBUG, ("Bicycle model was found:", country)); - return itr->second; - } - LOG(LDEBUG, ("Bicycle model wasn't found, default bicycle model is used instead:", country)); - return GetVehicleModel(); -} } // routing diff --git a/routing_common/bicycle_model.hpp b/routing_common/bicycle_model.hpp index d6f4a2b542..73deddd066 100644 --- a/routing_common/bicycle_model.hpp +++ b/routing_common/bicycle_model.hpp @@ -2,10 +2,6 @@ #include "routing_common/vehicle_model.hpp" -#include -#include -#include - namespace routing { @@ -37,15 +33,8 @@ private: class BicycleModelFactory : public VehicleModelFactory { public: - BicycleModelFactory(); - - /// @name Overrides from VehicleModelFactory. - //@{ - std::shared_ptr GetVehicleModel() const override; - std::shared_ptr GetVehicleModelForCountry(std::string const & country) const override; - //@} - -private: - std::unordered_map> m_models; + // TODO: remove countryParentNameGetterFn default value after removing unused bicycle routing + // from road_graph_router + BicycleModelFactory(CountryParentNameGetterFn const & countryParentNameGetterFn = {}); }; } // namespace routing diff --git a/routing_common/car_model.cpp b/routing_common/car_model.cpp index ac75baa22e..c7e806f3b9 100644 --- a/routing_common/car_model.cpp +++ b/routing_common/car_model.cpp @@ -236,7 +236,8 @@ vector const & CarModel::GetAdditiona return kAdditionalTags; } -CarModelFactory::CarModelFactory() +CarModelFactory::CarModelFactory(CountryParentNameGetterFn const & countryParentNameGetterFn) + : VehicleModelFactory(countryParentNameGetterFn) { // Names must be the same with country names from countries.txt m_models[""] = make_shared(g_carLimitsDefault); @@ -265,23 +266,4 @@ CarModelFactory::CarModelFactory() m_models["United Kingdom"] = make_shared(g_carLimitsUK); m_models["United States of America"] = make_shared(g_carLimitsUS); } - -shared_ptr CarModelFactory::GetVehicleModel() const -{ - auto const itr = m_models.find(""); - ASSERT(itr != m_models.end(), ()); - return itr->second; -} - -shared_ptr CarModelFactory::GetVehicleModelForCountry(string const & country) const -{ - auto const itr = m_models.find(country); - if (itr != m_models.end()) - { - LOG(LDEBUG, ("Car model was found:", country)); - return itr->second; - } - LOG(LDEBUG, ("Car model wasn't found, default car model is used instead:", country)); - return GetVehicleModel(); -} } // namespace routing diff --git a/routing_common/car_model.hpp b/routing_common/car_model.hpp index e5cd4aea90..ac8e0dabd8 100644 --- a/routing_common/car_model.hpp +++ b/routing_common/car_model.hpp @@ -2,10 +2,6 @@ #include "routing_common/vehicle_model.hpp" -#include -#include -#include - namespace routing { @@ -26,13 +22,6 @@ private: class CarModelFactory : public VehicleModelFactory { public: - CarModelFactory(); - - // VehicleModelFactory overrides: - std::shared_ptr GetVehicleModel() const override; - std::shared_ptr GetVehicleModelForCountry(std::string const & country) const override; - -private: - std::unordered_map> m_models; + CarModelFactory(CountryParentNameGetterFn const & countryParentNameGetterF); }; } // namespace routing diff --git a/routing_common/pedestrian_model.cpp b/routing_common/pedestrian_model.cpp index 137a85dbd8..c36c19b7f6 100644 --- a/routing_common/pedestrian_model.cpp +++ b/routing_common/pedestrian_model.cpp @@ -270,14 +270,7 @@ VehicleModel::InitListT const g_pedestrianLimitsUS = g_pedestrianLimitsAll; namespace routing { - -// If one of feature types will be disabled for pedestrian, features of this type will be simplyfied -// in generator. Look FeatureBuilder1::IsRoad() for more details. -PedestrianModel::PedestrianModel() - : VehicleModel(classif(), g_pedestrianLimitsAll) -{ - Init(); -} +PedestrianModel::PedestrianModel() : VehicleModel(classif(), g_pedestrianLimitsDefault) { Init(); } PedestrianModel::PedestrianModel(VehicleModel::InitListT const & speedLimits) : VehicleModel(classif(), speedLimits) @@ -301,7 +294,7 @@ void PedestrianModel::Init() SetAdditionalRoadTypes(classif(), additionalTags); } -IVehicleModel::RoadAvailability PedestrianModel::GetRoadAvailability(feature::TypesHolder const & types) const +VehicleModelInterface::RoadAvailability PedestrianModel::GetRoadAvailability(feature::TypesHolder const & types) const { if (types.Has(m_yesFootType)) return RoadAvailability::Available; @@ -310,14 +303,18 @@ IVehicleModel::RoadAvailability PedestrianModel::GetRoadAvailability(feature::Ty return RoadAvailability::Unknown; } +// If one of feature types will be disabled for pedestrian, features of this type will be simplyfied +// in generator. Look FeatureBuilder1::IsRoad() for more details. // static PedestrianModel const & PedestrianModel::AllLimitsInstance() { - static PedestrianModel const instance; + static PedestrianModel const instance(g_pedestrianLimitsAll); return instance; } -PedestrianModelFactory::PedestrianModelFactory() +PedestrianModelFactory::PedestrianModelFactory( + CountryParentNameGetterFn const & countryParentNameGetterFn) + : VehicleModelFactory(countryParentNameGetterFn) { // Names must be the same with country names from countries.txt m_models[""] = make_shared(g_pedestrianLimitsDefault); @@ -346,23 +343,4 @@ PedestrianModelFactory::PedestrianModelFactory() m_models["United Kingdom"] = make_shared(g_pedestrianLimitsUK); m_models["United States of America"] = make_shared(g_pedestrianLimitsUS); } - -shared_ptr PedestrianModelFactory::GetVehicleModel() const -{ - auto const itr = m_models.find(""); - ASSERT(itr != m_models.end(), ()); - return itr->second; -} - -shared_ptr PedestrianModelFactory::GetVehicleModelForCountry(string const & country) const -{ - auto const itr = m_models.find(country); - if (itr != m_models.end()) - { - LOG(LDEBUG, ("Pedestrian model was found:", country)); - return itr->second; - } - LOG(LDEBUG, ("Pedestrian model wasn't found, default model is used instead:", country)); - return GetVehicleModel(); -} } // routing diff --git a/routing_common/pedestrian_model.hpp b/routing_common/pedestrian_model.hpp index 5a36c447b9..be8f4aee95 100644 --- a/routing_common/pedestrian_model.hpp +++ b/routing_common/pedestrian_model.hpp @@ -2,10 +2,6 @@ #include "routing_common/vehicle_model.hpp" -#include -#include -#include - namespace routing { @@ -32,15 +28,8 @@ private: class PedestrianModelFactory : public VehicleModelFactory { public: - PedestrianModelFactory(); - - /// @name Overrides from VehicleModelFactory. - //@{ - std::shared_ptr GetVehicleModel() const override; - std::shared_ptr GetVehicleModelForCountry(std::string const & country) const override; - //@} - -private: - std::unordered_map> m_models; + // TODO: remove countryParentNameGetterFn default value after removing unused pedestrian routing + // from road_graph_router + PedestrianModelFactory(CountryParentNameGetterFn const & countryParentNameGetterFn = {}); }; } // namespace routing diff --git a/routing_common/routing_common_tests/CMakeLists.txt b/routing_common/routing_common_tests/CMakeLists.txt index 2e4a500e6b..e3d9029ab8 100644 --- a/routing_common/routing_common_tests/CMakeLists.txt +++ b/routing_common/routing_common_tests/CMakeLists.txt @@ -2,6 +2,7 @@ project(routing_common_tests) set( SRC + vehicle_model_for_country_test.cpp vehicle_model_test.cpp ) diff --git a/routing_common/routing_common_tests/routing_common_tests.pro b/routing_common/routing_common_tests/routing_common_tests.pro index 9ea3a558c6..f4e58be614 100644 --- a/routing_common/routing_common_tests/routing_common_tests.pro +++ b/routing_common/routing_common_tests/routing_common_tests.pro @@ -17,4 +17,5 @@ QT *= core SOURCES += \ ../../testing/testingmain.cpp \ + vehicle_model_for_country_test.cpp \ vehicle_model_test.cpp \ diff --git a/routing_common/routing_common_tests/vehicle_model_for_country_test.cpp b/routing_common/routing_common_tests/vehicle_model_for_country_test.cpp new file mode 100644 index 0000000000..a901364199 --- /dev/null +++ b/routing_common/routing_common_tests/vehicle_model_for_country_test.cpp @@ -0,0 +1,155 @@ +#include "testing/testing.hpp" + +#include "routing_common/bicycle_model.hpp" +#include "routing_common/car_model.hpp" +#include "routing_common/pedestrian_model.hpp" + +#include "indexer/classificator.hpp" +#include "indexer/classificator_loader.hpp" + +#include +#include + +using namespace routing; +using namespace std; + +namespace +{ +class VehicleModelTest +{ +public: + VehicleModelTest() { classificator::Load(); } +}; + +string GetRegionParent(string const & id) +{ + if (id == "Moscow") + return "Russian Federation"; + if (id == "Munich") + return "Bavaria"; + if (id == "Bavaria") + return "Germany"; + if (id == "San Francisco") + return "California"; + if (id == "California") + return "United States of America"; + return ""; +} + +template +void TestVehicleModelDefault() +{ + auto defaultVehicleModel = make_shared(); + + VehicleModelFactoryType vehicleModelFactory = VehicleModelFactoryType(GetRegionParent); + + // Use static_pointer_cast here because VehicleModelInterface do not have EqualsForTests method + shared_ptr defaultVehicleModelForCountry = static_pointer_cast( + vehicleModelFactory.GetVehicleModelForCountry("Nonexistent Country Name")); + TEST(defaultVehicleModel->EqualsForTests(*defaultVehicleModelForCountry), + ("Vehicle model for nonexistent counry is not equal to default.")); +} + +// DirectParent and IndirectParent tests require tested countries to have nondefault restriction +// If selected countries will change their restrictions to default, select other countries for tests +template +void TestHaveNondefaultRestrictionForSelectedCountry(string country) +{ + auto defaultVehicleModel = make_shared(); + + VehicleModelFactoryType vehicleModelFactory = VehicleModelFactoryType(GetRegionParent); + + shared_ptr vehicleModelCountry = + static_pointer_cast(vehicleModelFactory.GetVehicleModelForCountry(country)); + + TEST(!(vehicleModelCountry->EqualsForTests(*defaultVehicleModel)), + (country, + "has default model. It may be ok if traffic restrictions was changed. " + "If so, select other country for this and next test.")); +} + +template +void ParentTest(string child, string parent) +{ + VehicleModelFactoryType vehicleModelFactory = VehicleModelFactoryType(GetRegionParent); + + shared_ptr vehicleModelChild = + static_pointer_cast(vehicleModelFactory.GetVehicleModelForCountry(child)); + shared_ptr vehicleModelParent = + static_pointer_cast(vehicleModelFactory.GetVehicleModelForCountry(parent)); + + TEST(vehicleModelChild->EqualsForTests(*vehicleModelParent), + ("Can not expand car model for", child, "to", parent)); +} +} // namespace + +// Test we have default vehicle models for nonexistent(unknown) country +UNIT_CLASS_TEST(VehicleModelTest, CarModel_Default) +{ + TestVehicleModelDefault(); +} + +UNIT_CLASS_TEST(VehicleModelTest, BicycleModel_Default) +{ + TestVehicleModelDefault(); +} + +UNIT_CLASS_TEST(VehicleModelTest, PedestrianModel_Default) +{ + TestVehicleModelDefault(); +} + +// 1. Test we have nondefault car model for Russia +// 2. Test we can get car model for Moscow using GetRegionParent callback: car model for Moscow equals +// car model for Russia and it's not default model. +UNIT_CLASS_TEST(VehicleModelTest, CarModel_DirectParent) +{ + TestHaveNondefaultRestrictionForSelectedCountry("Russian Federation"); + ParentTest("Moscow", "Russian Federation"); +} + +// 1. Test we have nondefault bicycle model for Russia +// 2. Test we can get bicycle model for Moscow using GetRegionParent callback: bicycle model for Moscow +// equals bicycle model for Russia and it's not default model. +UNIT_CLASS_TEST(VehicleModelTest, BicycleModel_DirectParent) +{ + TestHaveNondefaultRestrictionForSelectedCountry( + "Russian Federation"); + ParentTest("Moscow", "Russian Federation"); +} + +// 1. Test we have nondefault pedestrian model for Russia +// 2. Test we can get pedestrian model for Moscow using GetRegionParent callback: pedestrian model for +// Moscow equals pedestrian model for Russia and it's not default model. +UNIT_CLASS_TEST(VehicleModelTest, PedestrianModel_DirectParent) +{ + TestHaveNondefaultRestrictionForSelectedCountry( + "Russian Federation"); + ParentTest("Moscow", "Russian Federation"); +} + +// Test has the same idea as previous one except Germany is not direct parent of Munich +// in GetRegionParent function: Munich -> Bavaria -> Germany +UNIT_CLASS_TEST(VehicleModelTest, CarModel_InirectParent) +{ + TestHaveNondefaultRestrictionForSelectedCountry("Germany"); + ParentTest("Munich", "Germany"); +} + +// Test has the same idea as previous one except United States of America are not direct parent of +// San Francisco in GetRegionParent function: San Francisco -> California -> United States of America +UNIT_CLASS_TEST(VehicleModelTest, BicycleModel_IndirectParent) +{ + TestHaveNondefaultRestrictionForSelectedCountry( + "United States of America"); + ParentTest("San Francisco", "United States of America"); +} + +// Test has the same idea as previous one except United States of America are not direct parent of +// San Francisco in GetRegionParent function: San Francisco -> California -> United States of America +UNIT_CLASS_TEST(VehicleModelTest, PedestrianModel_IndirectParent) +{ + TestHaveNondefaultRestrictionForSelectedCountry( + "United States of America"); + ParentTest("San Francisco", "United States of America"); +} diff --git a/routing_common/routing_common_tests/vehicle_model_test.cpp b/routing_common/routing_common_tests/vehicle_model_test.cpp index 91c1030372..af48d4af9c 100644 --- a/routing_common/routing_common_tests/vehicle_model_test.cpp +++ b/routing_common/routing_common_tests/vehicle_model_test.cpp @@ -18,6 +18,12 @@ routing::VehicleModel::InitListT const s_testLimits = { {{"highway", "service"}, 50, false}, }; +class VehicleModelTest +{ +public: + VehicleModelTest() { classificator::Load(); } +}; + class TestVehicleModel : public routing::VehicleModel { friend void CheckOneWay(initializer_list const & types, bool expectedValue); @@ -71,15 +77,13 @@ void CheckTransitAllowed(initializer_list const & types, bool expected } } // namespace -UNIT_TEST(VehicleModel_MaxSpeed) +UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_MaxSpeed) { - classificator::Load(); - TestVehicleModel vehicleModel; TEST_EQUAL(vehicleModel.GetMaxSpeed(), 150, ()); } -UNIT_TEST(VehicleModel_Speed) +UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_Speed) { CheckSpeed({GetType("highway", "secondary", "bridge")}, 80.0); CheckSpeed({GetType("highway", "secondary", "tunnel")}, 80.0); @@ -90,7 +94,7 @@ UNIT_TEST(VehicleModel_Speed) CheckSpeed({GetType("highway", "residential")}, 50.0); } -UNIT_TEST(VehicleModel_Speed_MultiTypes) +UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_Speed_MultiTypes) { uint32_t const typeTunnel = GetType("highway", "secondary", "tunnel"); uint32_t const typeSecondary = GetType("highway", "secondary"); @@ -101,7 +105,7 @@ UNIT_TEST(VehicleModel_Speed_MultiTypes) CheckSpeed({typeHighway, typeTunnel}, 80.0); } -UNIT_TEST(VehicleModel_OneWay) +UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_OneWay) { uint32_t const typeBridge = GetType("highway", "secondary", "bridge"); uint32_t const typeOneway = GetOnewayType(); @@ -114,7 +118,7 @@ UNIT_TEST(VehicleModel_OneWay) CheckOneWay({typeOneway}, true); } -UNIT_TEST(VehicleModel_DifferentSpeeds) +UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_DifferentSpeeds) { uint32_t const typeSecondary = GetType("highway", "secondary"); uint32_t const typePrimary = GetType("highway", "primary"); @@ -127,7 +131,7 @@ UNIT_TEST(VehicleModel_DifferentSpeeds) CheckOneWay({typePrimary, typeOneway, typeSecondary}, true); } -UNIT_TEST(VehicleModel_TransitAllowed) +UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_TransitAllowed) { CheckTransitAllowed({GetType("highway", "secondary")}, true); CheckTransitAllowed({GetType("highway", "primary")}, true); diff --git a/routing_common/vehicle_model.cpp b/routing_common/vehicle_model.cpp index 5acac26ac4..d3eda7041d 100644 --- a/routing_common/vehicle_model.cpp +++ b/routing_common/vehicle_model.cpp @@ -136,7 +136,7 @@ bool VehicleModel::IsRoadType(uint32_t type) const m_types.find(ftypes::BaseChecker::PrepareToMatch(type, 2)) != m_types.end(); } -IVehicleModel::RoadAvailability VehicleModel::GetRoadAvailability(feature::TypesHolder const & /* types */) const +VehicleModelInterface::RoadAvailability VehicleModel::GetRoadAvailability(feature::TypesHolder const & /* types */) const { return RoadAvailability::Unknown; } @@ -148,17 +148,57 @@ vector::const_iterator VehicleModel::FindRoadT [&type](AdditionalRoadType const & t) { return t.m_type == type; }); } -string DebugPrint(IVehicleModel::RoadAvailability const l) +VehicleModelFactory::VehicleModelFactory( + CountryParentNameGetterFn const & countryParentNameGetterFn) + : m_countryParentNameGetterFn(countryParentNameGetterFn) +{ +} + +shared_ptr VehicleModelFactory::GetVehicleModel() const +{ + auto const itr = m_models.find(""); + ASSERT(itr != m_models.end(), ("No default vehicle model. VehicleModelFactory was not " + "properly constructed")); + return itr->second; +} + +shared_ptr VehicleModelFactory::GetVehicleModelForCountry( + string const & country) const +{ + string parent = country; + while (!parent.empty()) + { + auto it = m_models.find(parent); + if (it != m_models.end()) + { + LOG(LDEBUG, ("Vehicle model for", country, " was found:", parent)); + return it->second; + } + parent = GetParent(parent); + } + + LOG(LDEBUG, ("Vehicle model wasn't found, default model is used instead:", country)); + return GetVehicleModel(); +} + +string VehicleModelFactory::GetParent(string const & country) const +{ + if (!m_countryParentNameGetterFn) + return string(); + return m_countryParentNameGetterFn(country); +} + +string DebugPrint(VehicleModelInterface::RoadAvailability const l) { switch (l) { - case IVehicleModel::RoadAvailability::Available: return "Available"; - case IVehicleModel::RoadAvailability::NotAvailable: return "NotAvailable"; - case IVehicleModel::RoadAvailability::Unknown: return "Unknown"; + case VehicleModelInterface::RoadAvailability::Available: return "Available"; + case VehicleModelInterface::RoadAvailability::NotAvailable: return "NotAvailable"; + case VehicleModelInterface::RoadAvailability::Unknown: return "Unknown"; } stringstream out; - out << "Unknown IVehicleModel::RoadAvailability (" << static_cast(l) << ")"; + out << "Unknown VehicleModelInterface::RoadAvailability (" << static_cast(l) << ")"; return out.str(); } } // namespace routing diff --git a/routing_common/vehicle_model.hpp b/routing_common/vehicle_model.hpp index 4f54aa34b7..4fbb6daf06 100644 --- a/routing_common/vehicle_model.hpp +++ b/routing_common/vehicle_model.hpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -14,7 +15,7 @@ namespace feature { class TypesHolder; } namespace routing { -class IVehicleModel +class VehicleModelInterface { public: enum class RoadAvailability @@ -24,7 +25,7 @@ public: Unknown, }; - virtual ~IVehicleModel() {} + virtual ~VehicleModelInterface() {} /// @return Allowed speed in KMpH. /// 0 means that it's forbidden to move on this feature or it's not a road at all. @@ -42,20 +43,20 @@ public: virtual bool IsTransitAllowed(FeatureType const & f) const = 0; }; -class VehicleModelFactory +class VehicleModelFactoryInterface { public: - virtual ~VehicleModelFactory() {} + virtual ~VehicleModelFactoryInterface() {} /// @return Default vehicle model which corresponds for all countrines, /// but it may be non optimal for some countries - virtual std::shared_ptr GetVehicleModel() const = 0; + virtual std::shared_ptr GetVehicleModel() const = 0; /// @return The most optimal vehicle model for specified country - virtual std::shared_ptr GetVehicleModelForCountry( + virtual std::shared_ptr GetVehicleModelForCountry( std::string const & country) const = 0; }; -class VehicleModel : public IVehicleModel +class VehicleModel : public VehicleModelInterface { public: struct FeatureTypeLimits final @@ -82,7 +83,7 @@ public: VehicleModel(Classificator const & c, InitListT const & featureTypeLimits); - /// IVehicleModel overrides: + /// VehicleModelInterface overrides: double GetSpeed(FeatureType const & f) const override; double GetMaxSpeed() const override { return m_maxSpeedKMpH; } bool IsOneWay(FeatureType const & f) const override; @@ -104,6 +105,13 @@ public: return false; } + bool EqualsForTests(VehicleModel const & rhs) const + { + return (m_types == rhs.m_types) && + (m_addRoadTypes == rhs.m_addRoadTypes) && + (m_onewayType == rhs.m_onewayType); + } + protected: /// @returns a special restriction which is set to the feature. virtual RoadAvailability GetRoadAvailability(feature::TypesHolder const & types) const; @@ -143,6 +151,10 @@ private: double GetSpeedKMpH() const { return m_speedKMpH; }; bool IsTransitAllowed() const { return m_isTransitAllowed; }; + bool operator==(RoadLimits const & rhs) const + { + return (m_speedKMpH == rhs.m_speedKMpH) && (m_isTransitAllowed == rhs.m_isTransitAllowed); + } private: double const m_speedKMpH; @@ -157,5 +169,28 @@ private: uint32_t m_onewayType; }; -std::string DebugPrint(IVehicleModel::RoadAvailability const l); +class VehicleModelFactory : public VehicleModelFactoryInterface +{ +public: + // Callback which takes territory name (mwm graph node name) and returns its parent + // territory name. Used to properly find local restrictions in GetVehicleModelForCountry. + // For territories which do not have parent (countries) or have multiple parents + // (disputed territories) it should return empty name. + // For example "Munich" -> "Bavaria"; "Bavaria" -> "Germany"; "Germany" -> "" + using CountryParentNameGetterFn = std::function; + + std::shared_ptr GetVehicleModel() const override; + + std::shared_ptr GetVehicleModelForCountry( + std::string const & country) const override; + +protected: + VehicleModelFactory(CountryParentNameGetterFn const & countryParentNameGetterFn); + std::string GetParent(std::string const & country) const; + + std::unordered_map> m_models; + CountryParentNameGetterFn m_countryParentNameGetterFn; +}; + +std::string DebugPrint(VehicleModelInterface::RoadAvailability const l); } // namespace routing diff --git a/storage/CMakeLists.txt b/storage/CMakeLists.txt index ce55713621..b681a692a8 100644 --- a/storage/CMakeLists.txt +++ b/storage/CMakeLists.txt @@ -13,6 +13,8 @@ set( country_info_getter.hpp country_name_getter.cpp country_name_getter.hpp + country_parent_getter.cpp + country_parent_getter.hpp country_polygon.hpp country_tree.hpp diff_scheme/diff_scheme_checker.cpp diff --git a/storage/country_parent_getter.cpp b/storage/country_parent_getter.cpp new file mode 100644 index 0000000000..fe1a541fbf --- /dev/null +++ b/storage/country_parent_getter.cpp @@ -0,0 +1,18 @@ +#include "storage/country_parent_getter.hpp" + +namespace storage +{ +CountryParentGetter::CountryParentGetter(std::string const & countriesFile, + std::string const & countriesDir) +{ + if (countriesFile.empty()) + m_storage = make_shared(); + else + m_storage = make_shared(countriesFile, countriesDir); +} + +std::string CountryParentGetter::operator()(std::string const & id) const +{ + return m_storage->GetParentIdFor(id); +} +} // namespace storage diff --git a/storage/country_parent_getter.hpp b/storage/country_parent_getter.hpp new file mode 100644 index 0000000000..35ed843eec --- /dev/null +++ b/storage/country_parent_getter.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include "storage/storage.hpp" + +#include +#include + +namespace storage +{ +class CountryParentGetter +{ +public: + CountryParentGetter(std::string const & countriesFile = "", + std::string const & countriesDir = ""); + std::string operator()(std::string const & id) const; + +private: + shared_ptr m_storage; +}; +} // namespace storage diff --git a/storage/storage.cpp b/storage/storage.cpp index 8b874ec683..866f29a099 100644 --- a/storage/storage.cpp +++ b/storage/storage.cpp @@ -1680,4 +1680,22 @@ void Storage::GetTopmostNodesFor(TCountryId const & countryId, TCountriesVec & n } } +TCountryId const Storage::GetParentIdFor(TCountryId const & countryId) const +{ + vector nodes; + m_countries.Find(countryId, nodes); + if (nodes.empty()) + { + LOG(LWARNING, ("TCountryId =", countryId, "not found in m_countries.")); + return string(); + } + + if (nodes.size() > 1) + { + // Disputed territory. Has multiple parents. + return string(); + } + + return nodes[0]->Value().GetParent(); +} } // namespace storage diff --git a/storage/storage.hpp b/storage/storage.hpp index cf753e040f..d93f0a820b 100644 --- a/storage/storage.hpp +++ b/storage/storage.hpp @@ -365,6 +365,10 @@ public: /// Puts |countryId| to |nodes| when |level| is greater than the level of |countyId|. void GetTopmostNodesFor(TCountryId const & countryId, TCountriesVec & nodes, size_t level = 0) const; + /// \brief Returns parent id for node if node has single parent. Otherwise (if node is disputed + /// territory and has multiple parents or does not exist) returns empty TCountryId + TCountryId const GetParentIdFor(TCountryId const & countryId) const; + /// \brief Returns current version for mwms which are used by storage. inline int64_t GetCurrentDataVersion() const { return m_currentVersion; } diff --git a/storage/storage.pro b/storage/storage.pro index bcafbcb1ab..81860a7b2c 100644 --- a/storage/storage.pro +++ b/storage/storage.pro @@ -15,6 +15,7 @@ HEADERS += \ country_decl.hpp \ country_info_getter.hpp \ country_name_getter.hpp \ + country_parent_getter.hpp \ country_polygon.hpp \ country_tree.hpp \ diff_scheme/diff_scheme_checker.hpp \ @@ -34,6 +35,7 @@ SOURCES += \ country_decl.cpp \ country_info_getter.cpp \ country_name_getter.cpp \ + country_parent_getter.cpp \ diff_scheme/diff_scheme_checker.cpp \ downloading_policy.cpp \ http_map_files_downloader.cpp \ diff --git a/xcode/routing_common/routing_common.xcodeproj/project.pbxproj b/xcode/routing_common/routing_common.xcodeproj/project.pbxproj index 56f26afbe2..17da24f5dd 100644 --- a/xcode/routing_common/routing_common.xcodeproj/project.pbxproj +++ b/xcode/routing_common/routing_common.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 40FF45D01F388EF80046BD40 /* vehicle_model_for_country_test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 40FF45CF1F388EF80046BD40 /* vehicle_model_for_country_test.cpp */; }; 671E78881E6A3C5D00B2859B /* bicycle_model.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 671E78801E6A3C5D00B2859B /* bicycle_model.cpp */; }; 671E78891E6A3C5D00B2859B /* bicycle_model.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 671E78811E6A3C5D00B2859B /* bicycle_model.hpp */; }; 671E788A1E6A3C5D00B2859B /* car_model.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 671E78821E6A3C5D00B2859B /* car_model.cpp */; }; @@ -34,6 +35,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 40FF45CF1F388EF80046BD40 /* vehicle_model_for_country_test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = vehicle_model_for_country_test.cpp; sourceTree = ""; }; 671E78721E6A3BE200B2859B /* librouting_common.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = librouting_common.a; sourceTree = BUILT_PRODUCTS_DIR; }; 671E78801E6A3C5D00B2859B /* bicycle_model.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bicycle_model.cpp; sourceTree = ""; }; 671E78811E6A3C5D00B2859B /* bicycle_model.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = bicycle_model.hpp; sourceTree = ""; }; @@ -136,6 +138,7 @@ 671E78971E6A3DA800B2859B /* routing_common_tests */ = { isa = PBXGroup; children = ( + 40FF45CF1F388EF80046BD40 /* vehicle_model_for_country_test.cpp */, 671E78AF1E6A3FEF00B2859B /* testingmain.cpp */, 671E78AD1E6A3FDB00B2859B /* vehicle_model_test.cpp */, ); @@ -271,6 +274,7 @@ 671E788A1E6A3C5D00B2859B /* car_model.cpp in Sources */, 671E78881E6A3C5D00B2859B /* bicycle_model.cpp in Sources */, 671E788E1E6A3C5D00B2859B /* vehicle_model.cpp in Sources */, + 40FF45D01F388EF80046BD40 /* vehicle_model_for_country_test.cpp in Sources */, 671E788C1E6A3C5D00B2859B /* pedestrian_model.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/xcode/storage/storage.xcodeproj/project.pbxproj b/xcode/storage/storage.xcodeproj/project.pbxproj index 378f497db7..ebb0cd1587 100644 --- a/xcode/storage/storage.xcodeproj/project.pbxproj +++ b/xcode/storage/storage.xcodeproj/project.pbxproj @@ -17,6 +17,8 @@ 34B093261C61F9BA0066F4C3 /* app_store.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 34B093211C61F9BA0066F4C3 /* app_store.hpp */; }; 34C9BCFC1C6CCF85000DC38D /* country_name_getter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 34C9BCFA1C6CCF85000DC38D /* country_name_getter.cpp */; }; 34C9BCFD1C6CCF85000DC38D /* country_name_getter.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 34C9BCFB1C6CCF85000DC38D /* country_name_getter.hpp */; }; + 401ECED41F56C50900DFDF76 /* country_parent_getter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 401ECED21F56C50900DFDF76 /* country_parent_getter.cpp */; }; + 401ECED51F56C50900DFDF76 /* country_parent_getter.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 401ECED31F56C50900DFDF76 /* country_parent_getter.hpp */; }; 56D8CB991CAC17A80003F420 /* test_defines.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 56D8CB971CAC17A80003F420 /* test_defines.cpp */; }; 56D8CB9A1CAC17A80003F420 /* test_defines.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 56D8CB981CAC17A80003F420 /* test_defines.hpp */; }; 671182CE1C7E06B400CB8177 /* storage_3levels_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 671182CC1C7E069C00CB8177 /* storage_3levels_tests.cpp */; }; @@ -186,6 +188,8 @@ 34C9BCFB1C6CCF85000DC38D /* country_name_getter.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = country_name_getter.hpp; sourceTree = ""; }; 34F5584A1DBF2FC000A4FC11 /* common-debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "common-debug.xcconfig"; path = "../common-debug.xcconfig"; sourceTree = ""; }; 34F5584B1DBF2FC000A4FC11 /* common-release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "common-release.xcconfig"; path = "../common-release.xcconfig"; sourceTree = ""; }; + 401ECED21F56C50900DFDF76 /* country_parent_getter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = country_parent_getter.cpp; sourceTree = ""; }; + 401ECED31F56C50900DFDF76 /* country_parent_getter.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = country_parent_getter.hpp; sourceTree = ""; }; 56D8CB971CAC17A80003F420 /* test_defines.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = test_defines.cpp; sourceTree = ""; }; 56D8CB981CAC17A80003F420 /* test_defines.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = test_defines.hpp; sourceTree = ""; }; 671182CC1C7E069C00CB8177 /* storage_3levels_tests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = storage_3levels_tests.cpp; sourceTree = ""; }; @@ -510,6 +514,8 @@ 675342E21A3F59EF00A0A8C3 /* storage */ = { isa = PBXGroup; children = ( + 401ECED21F56C50900DFDF76 /* country_parent_getter.cpp */, + 401ECED31F56C50900DFDF76 /* country_parent_getter.hpp */, F68CC5BB1F38B967007527C7 /* diff_scheme_checker.cpp */, F68CC5BC1F38B967007527C7 /* diff_scheme_checker.hpp */, F68CC5BD1F38B967007527C7 /* diff_types.hpp */, @@ -585,6 +591,7 @@ 56D8CB9A1CAC17A80003F420 /* test_defines.hpp in Headers */, 6753430D1A3F5A2600A0A8C3 /* country_polygon.hpp in Headers */, F68CC5C01F38B967007527C7 /* diff_types.hpp in Headers */, + 401ECED51F56C50900DFDF76 /* country_parent_getter.hpp in Headers */, 34C9BCFD1C6CCF85000DC38D /* country_name_getter.hpp in Headers */, 6741251F1B4C05FA00A3E828 /* http_map_files_downloader.hpp in Headers */, 67BE1DC61CD2180D00572709 /* downloading_policy.hpp in Headers */, @@ -765,6 +772,7 @@ buildActionMask = 2147483647; files = ( 56D8CB991CAC17A80003F420 /* test_defines.cpp in Sources */, + 401ECED41F56C50900DFDF76 /* country_parent_getter.cpp in Sources */, 6753430E1A3F5A2600A0A8C3 /* country.cpp in Sources */, 67AF4A001BC579DD0048B1ED /* country_info_getter.cpp in Sources */, 34B093221C61F9BA0066F4C3 /* storage_helpers.cpp in Sources */,