diff --git a/generator/aggregating_sponsored_dataset.cpp b/generator/aggregating_sponsored_dataset.cpp new file mode 100644 index 0000000000..b49845a19e --- /dev/null +++ b/generator/aggregating_sponsored_dataset.cpp @@ -0,0 +1,24 @@ +#include "generator/aggregating_sponsored_dataset.hpp" + +namespace generator +{ +SponsoredDataset::ObjectId AggregatingSponsoredDataset::FindMatchingObjectId(FeatureBuilder1 const & fb) const +{ + // There is only one source for now. + return m_datasets[0]->FindMatchingObjectId(fb); +} + +size_t AggregatingSponsoredDataset::Size() const +{ + size_t count{}; + for (auto const & ds : m_datasets) + count += ds->Size(); + return count; +} + +void AggregatingSponsoredDataset::BuildOsmObjects(function const & fn) const +{ + for (auto const & ds : m_datasets) + ds->BuildOsmObjects(fn); +} +} // namespace generator diff --git a/generator/aggregating_sponsored_dataset.hpp b/generator/aggregating_sponsored_dataset.hpp new file mode 100644 index 0000000000..d9f90098fb --- /dev/null +++ b/generator/aggregating_sponsored_dataset.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include "generator/booking_dataset.hpp" +#include "generator/generate_info.hpp" + +#include "std/unique_ptr.hpp" +#include "std/vector.hpp" + +namespace generator +{ +class AggregatingSponsoredDataset : public SponsoredDataset +{ +public: + explicit AggregatingSponsoredDataset(feature::GenerateInfo const & info) + { + m_datasets.emplace_back(make_unique(info.m_bookingDatafileName, + info.m_bookingReferenceDir)); + } + + ObjectId FindMatchingObjectId(FeatureBuilder1 const & e) const override; + + size_t Size() const override; + + void BuildOsmObjects(function const & fn) const override; + +private: + vector> m_datasets; +}; +} // namespace generator; diff --git a/generator/booking_dataset.cpp b/generator/booking_dataset.cpp index 3521df0092..b81800ecd6 100644 --- a/generator/booking_dataset.cpp +++ b/generator/booking_dataset.cpp @@ -10,38 +10,6 @@ namespace generator { -// BookingDataset::AddressMatcher::AddressMatcher() -// { -// vector localFiles; - -// Platform & platform = GetPlatform(); -// platform::FindAllLocalMapsInDirectoryAndCleanup(platform.WritableDir(), 0 /* version */, -// -1 /* latestVersion */, localFiles); - -// for (platform::LocalCountryFile const & localFile : localFiles) -// { -// LOG(LINFO, ("Found mwm:", localFile)); -// try -// { -// m_index.RegisterMap(localFile); -// } -// catch (RootException const & ex) -// { -// CHECK(false, ("Bad mwm file:", localFile)); -// } -// } - -// m_coder = make_unique(m_index); -// } - -// void BookingDataset::AddressMatcher::operator()(Hotel & hotel) -// { -// search::ReverseGeocoder::Address addr; -// m_coder->GetNearbyAddress(MercatorBounds::FromLatLon(hotel.lat, hotel.lon), addr); -// hotel.street = addr.GetStreetName(); -// hotel.houseNumber = addr.GetHouseNumber(); -// } - bool BookingDataset::NecessaryMatchingConditionHolds(FeatureBuilder1 const & fb) const { if (fb.GetName(StringUtf8Multilang::kDefaultCode).empty()) @@ -59,6 +27,7 @@ void BookingDataset::BuildObject(SponsoredDataset::Object const & hotel, fb.SetCenter(MercatorBounds::FromLatLon(hotel.lat, hotel.lon)); auto & metadata = params.GetMetadata(); + // TODO(mgsergio): Rename FMD_SPONSORED_ID to FMD_BOOKING_ID. metadata.Set(feature::Metadata::FMD_SPONSORED_ID, strings::to_string(hotel.id.Get())); metadata.Set(feature::Metadata::FMD_WEBSITE, hotel.descUrl); metadata.Set(feature::Metadata::FMD_RATING, strings::to_string(hotel.ratingUser)); diff --git a/generator/booking_dataset.hpp b/generator/booking_dataset.hpp index 5c7b547b7d..4d0ab6fa34 100644 --- a/generator/booking_dataset.hpp +++ b/generator/booking_dataset.hpp @@ -1,22 +1,22 @@ #pragma once -#include "indexer/index.hpp" - #include "generator/sponsored_dataset.hpp" +#include "indexer/index.hpp" + #include "search/reverse_geocoder.hpp" #include "base/newtype.hpp" -#include "boost/geometry.hpp" -#include "boost/geometry/geometries/point.hpp" -#include "boost/geometry/geometries/box.hpp" -#include "boost/geometry/index/rtree.hpp" - #include "std/function.hpp" #include "std/map.hpp" #include "std/string.hpp" +#include "boost/geometry.hpp" +#include "boost/geometry/geometries/box.hpp" +#include "boost/geometry/geometries/point.hpp" +#include "boost/geometry/index/rtree.hpp" + class FeatureBuilder1; namespace generator @@ -25,22 +25,11 @@ class BookingDataset : public SponsoredDatasetBase { public: - // class AddressMatcher - // { - // Index m_index; - // unique_ptr m_coder; - - // public: - // AddressMatcher(); - // void operator()(Hotel & hotel); - // }; - explicit BookingDataset(string const & dataPath, string const & addressReferencePath = string()) : SponsoredDatasetBase(dataPath, addressReferencePath) { } - explicit BookingDataset(istream & dataSource, string const & addressReferencePath = string()) : SponsoredDatasetBase(dataSource, addressReferencePath) { diff --git a/generator/generator.pro b/generator/generator.pro index ebd6d9923c..35cae7dbd6 100644 --- a/generator/generator.pro +++ b/generator/generator.pro @@ -15,6 +15,7 @@ INCLUDEPATH *= $$ROOT_DIR/3party/gflags/src \ QT *= core SOURCES += \ + aggregating_sponsored_dataset.cpp \ altitude_generator.cpp \ booking_dataset.cpp \ booking_scoring.cpp \ @@ -44,6 +45,7 @@ SOURCES += \ unpack_mwm.cpp \ HEADERS += \ + aggregating_sponsored_dataset.hpp \ altitude_generator.hpp \ booking_dataset.hpp \ booking_scoring.hpp \ diff --git a/generator/osm_source.cpp b/generator/osm_source.cpp index 37b84456c4..8972e98b91 100644 --- a/generator/osm_source.cpp +++ b/generator/osm_source.cpp @@ -1,4 +1,4 @@ -#include "generator/booking_dataset.hpp" +#include "generator/aggregating_sponsored_dataset.hpp" #include "generator/coastlines_generator.hpp" #include "generator/feature_generator.hpp" #include "generator/intermediate_data.hpp" @@ -277,7 +277,7 @@ class MainFeaturesEmitter : public EmitterBase string m_srcCoastsFile; bool m_failOnCoasts; - generator::BookingDataset m_bookingDataset; + generator::AggregatingSponsoredDataset m_dataset; /// Used to prepare a list of cities to serve as a list of nodes /// for building a highway graph with OSRM for low zooms. @@ -300,7 +300,7 @@ public: MainFeaturesEmitter(feature::GenerateInfo const & info) : m_skippedElementsPath(info.GetIntermediateFileName("skipped_elements", ".lst")) , m_failOnCoasts(info.m_failOnCoasts) - , m_bookingDataset(info.m_bookingDatafileName, info.m_bookingReferenceDir) + , m_dataset(info) { Classificator const & c = classif(); @@ -349,7 +349,7 @@ public: [](Place const & p1, Place const & p2) { return p1.IsEqual(p2); }, [](Place const & p1, Place const & p2) { return p1.IsBetterThan(p2); }); } - else if (m_bookingDataset.FindMatchingObjectId(fb) != + else if (m_dataset.FindMatchingObjectId(fb) != generator::SponsoredDatasetBase::kInvalidObjectId) { m_skippedElements << DebugPrint(fb.GetMostGenericOsmId()) << endl; @@ -389,7 +389,7 @@ public: DumpSkippedElements(); // Emit all booking objecs to the map. - m_bookingDataset.BuildOsmObjects([this](FeatureBuilder1 & fb) { Emit(fb); }); + m_dataset.BuildOsmObjects([this](FeatureBuilder1 & fb) { Emit(fb); }); m_places.ForEach([this](Place const & p) { diff --git a/generator/sponsored_dataset.cpp b/generator/sponsored_dataset.cpp index 12cbd28a45..4a7f885ea7 100644 --- a/generator/sponsored_dataset.cpp +++ b/generator/sponsored_dataset.cpp @@ -1,5 +1,7 @@ #include "generator/sponsored_dataset.hpp" +#include "platform/local_country_file.hpp" +#include "platform/local_country_file_utils.hpp" #include "platform/platform.hpp" #include "geometry/distance_on_sphere.hpp" @@ -7,10 +9,9 @@ #include "base/logging.hpp" #include "base/string_utils.hpp" -#include "std/limits.hpp" - #include "std/fstream.hpp" #include "std/iostream.hpp" +#include "std/limits.hpp" namespace generator { @@ -30,6 +31,38 @@ string EscapeTabs(string const & str) } } // namespace +SponsoredDataset::AddressMatcher::AddressMatcher() +{ + vector localFiles; + + Platform & platform = GetPlatform(); + platform::FindAllLocalMapsInDirectoryAndCleanup(platform.WritableDir(), 0 /* version */, + -1 /* latestVersion */, localFiles); + + for (platform::LocalCountryFile const & localFile : localFiles) + { + LOG(LINFO, ("Found mwm:", localFile)); + try + { + m_index.RegisterMap(localFile); + } + catch (RootException const & ex) + { + CHECK(false, ("Bad mwm file:", localFile)); + } + } + + m_coder = make_unique(m_index); +} + +void SponsoredDataset::AddressMatcher::operator()(Object & object) +{ + search::ReverseGeocoder::Address addr; + m_coder->GetNearbyAddress(MercatorBounds::FromLatLon(object.lat, object.lon), addr); + object.street = addr.GetStreetName(); + object.houseNumber = addr.GetHouseNumber(); +} + SponsoredDataset::Object::Object(string const & src) { vector rec; @@ -151,18 +184,18 @@ void SponsoredDatasetBase::LoadData(istream & src, string const & addressReferen string const backupPath = platform.WritableDir(); platform.SetWritableDirForTests(addressReferencePath); - //TODO(mgsergio): AddressMatcher addressMatcher; + AddressMatcher addressMatcher; size_t matchedNum = 0; size_t emptyAddr = 0; for (auto & item : m_hotels) { - auto & hotel = item.second; - // TODO(mgsergio): addressMatcher(hotel); + auto & object = item.second; + addressMatcher(object); - if (hotel.address.empty()) + if (object.address.empty()) ++emptyAddr; - if (hotel.IsAddressPartsFilled()) + if (object.IsAddressPartsFilled()) ++matchedNum; } LOG(LINFO, diff --git a/generator/sponsored_dataset.hpp b/generator/sponsored_dataset.hpp index 6f83fe6a3e..e24b9066af 100644 --- a/generator/sponsored_dataset.hpp +++ b/generator/sponsored_dataset.hpp @@ -6,16 +6,16 @@ #include "base/newtype.hpp" -#include "boost/geometry.hpp" -#include "boost/geometry/geometries/point.hpp" -#include "boost/geometry/geometries/box.hpp" -#include "boost/geometry/index/rtree.hpp" - #include "std/function.hpp" #include "std/limits.hpp" #include "std/map.hpp" #include "std/string.hpp" +#include "boost/geometry.hpp" +#include "boost/geometry/geometries/point.hpp" +#include "boost/geometry/geometries/box.hpp" +#include "boost/geometry/index/rtree.hpp" + class FeatureBuilder1; namespace generator @@ -71,20 +71,20 @@ public: inline bool IsAddressPartsFilled() const { return !street.empty() || !houseNumber.empty(); } }; - // class AddressMatcher - // { - // Index m_index; - // unique_ptr m_coder; + class AddressMatcher + { + Index m_index; + unique_ptr m_coder; - // public: - // AddressMatcher(); - // void operator()(Hotel & hotel); - // }; + public: + AddressMatcher(); + void operator()(Object & object); + }; virtual ~SponsoredDataset() = default; - // TODO(mgsergio): Comment /// @return an id of a matched hotel or kInvalidHotelIndex on failure. - virtual ObjectId FindMatchingObjectId(FeatureBuilder1 const & e) const = 0; + /// @return an id of a matched object or kInvalidObjectId on failure. + virtual ObjectId FindMatchingObjectId(FeatureBuilder1 const & fb) const = 0; virtual size_t Size() const = 0; @@ -111,7 +111,6 @@ public: /// @return true if |fb| satisfies some necesary conditions to match one or serveral /// objects from dataset. virtual bool NecessaryMatchingConditionHolds(FeatureBuilder1 const & fb) const = 0; - /// @return an id of a matched object or kInvalidObjectId on failure. ObjectId FindMatchingObjectId(FeatureBuilder1 const & e) const override; void BuildOsmObjects(function const & fn) const override; @@ -131,6 +130,6 @@ protected: void LoadData(istream & src, string const & addressReferencePath); /// @return an id of a matched object or kInvalidObjectId on failure. - virtual ObjectId FindMatchingObjectIdImpl(FeatureBuilder1 const & e) const = 0; + virtual ObjectId FindMatchingObjectIdImpl(FeatureBuilder1 const & fb) const = 0; }; } // namespace generator diff --git a/generator/sponsored_object.hpp b/generator/sponsored_object.hpp deleted file mode 100644 index c73ada6b95..0000000000 --- a/generator/sponsored_object.hpp +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -NEWTYPE(uint32_t, ObjectId); -NEWTYPE_SIMPLE_OUTPUT(ObjectId); - -static double constexpr kDistanceLimitInMeters = 150; -static size_t constexpr kMaxSelectedElements = 3; -static ObjectId const kInvalidObjectId; - -struct SponsoredObject -{ - enum class Fields - { - Id = 0, - Latitude = 1, - Longtitude = 2, - Name = 3, - Address = 4, - Stars = 5, - PriceCategory = 6, - RatingBooking = 7, - RatingUsers = 8, - DescUrl = 9, - Type = 10, - Translations = 11, - - Counter - }; - - ObjectId id{kInvalidObjectId}; - double lat = 0.0; - double lon = 0.0; - string name; - string address; - string street; - string houseNumber; - uint32_t stars = 0; - uint32_t priceCategory = 0; - double ratingBooking = 0.0; - double ratingUser = 0.0; - string descUrl; - uint32_t type = 0; - string translations; - - static size_t constexpr Index(Fields field) { return static_cast(field); } - static size_t constexpr FieldsCount() { return static_cast(Fields::Counter); } - explicit SponsoredObject(string const & src); - - inline bool IsAddressFilled() const { return !street.empty() || !houseNumber.empty(); } -}; - -ostream & operator<<(ostream & s, BookingDataset::Hotel const & h);