forked from organicmaps/organicmaps
Use NewType for bookingid.
This commit is contained in:
parent
569ea6f284
commit
78ea6a4038
4 changed files with 36 additions and 29 deletions
|
@ -36,13 +36,15 @@ string EscapeTabs(string const & str)
|
|||
}
|
||||
} // namespace
|
||||
|
||||
BookingDataset::BookingId const BookingDataset::kInvalidHotelIndex = BookingId(numeric_limits<BookingId::RepType>::max());
|
||||
|
||||
BookingDataset::Hotel::Hotel(string const & src)
|
||||
{
|
||||
vector<string> rec;
|
||||
strings::ParseCSVRow(src, '\t', rec);
|
||||
CHECK(rec.size() == FieldsCount(), ("Error parsing hotels.tsv line:", EscapeTabs(src)));
|
||||
|
||||
strings::to_uint(rec[Index(Fields::Id)], id);
|
||||
strings::to_uint(rec[Index(Fields::Id)], id.Get());
|
||||
strings::to_double(rec[Index(Fields::Latitude)], lat);
|
||||
strings::to_double(rec[Index(Fields::Longtitude)], lon);
|
||||
|
||||
|
@ -120,7 +122,7 @@ BookingDataset::BookingDataset(istream & dataSource, string const & addressRefer
|
|||
LoadHotels(dataSource, addressReferencePath);
|
||||
}
|
||||
|
||||
size_t BookingDataset::GetMatchingHotelIndex(FeatureBuilder1 const & fb) const
|
||||
BookingDataset::BookingId BookingDataset::GetMatchingHotelId(FeatureBuilder1 const & fb) const
|
||||
{
|
||||
if (CanBeBooking(fb))
|
||||
return MatchWithBooking(fb);
|
||||
|
@ -135,26 +137,27 @@ bool BookingDataset::CanBeBooking(FeatureBuilder1 const & fb) const
|
|||
return ftypes::IsHotelChecker::Instance()(fb.GetTypes());
|
||||
}
|
||||
|
||||
BookingDataset::Hotel const & BookingDataset::GetHotelById(uint32_t const id) const
|
||||
BookingDataset::Hotel const & BookingDataset::GetHotelById(BookingId const id) const
|
||||
{
|
||||
auto const it = m_hotels.find(id);
|
||||
CHECK(it != end(m_hotels), ("Got wrong hotel id:", id));
|
||||
return it->second;
|
||||
}
|
||||
|
||||
BookingDataset::Hotel & BookingDataset::GetHotelById(uint32_t const id)
|
||||
BookingDataset::Hotel & BookingDataset::GetHotelById(BookingId const id)
|
||||
{
|
||||
auto it = m_hotels.find(id);
|
||||
CHECK(it != end(m_hotels), ("Got wrong hotel id:", id));
|
||||
return it->second;
|
||||
}
|
||||
|
||||
vector<uint32_t> BookingDataset::GetNearestHotels(ms::LatLon const & latLon, size_t const limit,
|
||||
double const maxDistance /* = 0.0 */) const
|
||||
vector<BookingDataset::BookingId> BookingDataset::GetNearestHotels(
|
||||
ms::LatLon const & latLon, size_t const limit,
|
||||
double const maxDistance /* = 0.0 */) const
|
||||
{
|
||||
namespace bgi = boost::geometry::index;
|
||||
|
||||
vector<uint32_t> indexes;
|
||||
vector<BookingId> indexes;
|
||||
for_each(bgi::qbegin(m_rtree, bgi::nearest(TPoint(latLon.lat, latLon.lon), limit)),
|
||||
bgi::qend(m_rtree), [this, &latLon, &indexes, maxDistance](TValue const & v)
|
||||
{
|
||||
|
@ -184,7 +187,7 @@ void BookingDataset::BuildHotel(Hotel const & hotel,
|
|||
fb.SetCenter(MercatorBounds::FromLatLon(hotel.lat, hotel.lon));
|
||||
|
||||
auto & metadata = params.GetMetadata();
|
||||
metadata.Set(feature::Metadata::FMD_SPONSORED_ID, strings::to_string(hotel.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));
|
||||
metadata.Set(feature::Metadata::FMD_STARS, strings::to_string(hotel.stars));
|
||||
|
@ -318,18 +321,18 @@ void BookingDataset::LoadHotels(istream & src, string const & addressReferencePa
|
|||
}
|
||||
}
|
||||
|
||||
size_t BookingDataset::MatchWithBooking(FeatureBuilder1 const & fb) const
|
||||
BookingDataset::BookingId BookingDataset::MatchWithBooking(FeatureBuilder1 const & fb) const
|
||||
{
|
||||
auto const name = fb.GetName(StringUtf8Multilang::kDefaultCode);
|
||||
|
||||
if (name.empty())
|
||||
return false;
|
||||
return kInvalidHotelIndex;
|
||||
|
||||
// Find |kMaxSelectedElements| nearest values to a point.
|
||||
auto const bookingIndexes = GetNearestHotels(MercatorBounds::ToLatLon(fb.GetKeyPoint()),
|
||||
kMaxSelectedElements, kDistanceLimitInMeters);
|
||||
|
||||
for (uint32_t const j : bookingIndexes)
|
||||
for (auto const j : bookingIndexes)
|
||||
{
|
||||
if (booking_scoring::Match(GetHotelById(j), fb).IsMatched())
|
||||
return j;
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
#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"
|
||||
|
@ -21,9 +23,11 @@ namespace generator
|
|||
class BookingDataset
|
||||
{
|
||||
public:
|
||||
NEWTYPE(uint32_t, BookingId);
|
||||
|
||||
static double constexpr kDistanceLimitInMeters = 150;
|
||||
static size_t constexpr kMaxSelectedElements = 3;
|
||||
static auto constexpr kInvalidHotelIndex = numeric_limits<uint32_t>::max();
|
||||
static BookingId const kInvalidHotelIndex;
|
||||
|
||||
struct Hotel
|
||||
{
|
||||
|
@ -45,8 +49,7 @@ public:
|
|||
Counter
|
||||
};
|
||||
|
||||
// TODO(mgsergio): Make a separate type for this or an alias.
|
||||
uint32_t id = 0;
|
||||
BookingId id{kInvalidHotelIndex};
|
||||
double lat = 0.0;
|
||||
double lon = 0.0;
|
||||
string name;
|
||||
|
@ -81,26 +84,26 @@ public:
|
|||
explicit BookingDataset(string const & dataPath, string const & addressReferencePath = string());
|
||||
explicit BookingDataset(istream & dataSource, string const & addressReferencePath = string());
|
||||
|
||||
/// @return an index of a matched hotel or kInvalidHotelIndex on failure.
|
||||
size_t GetMatchingHotelIndex(FeatureBuilder1 const & fb) const;
|
||||
/// @return an id of a matched hotel or kInvalidHotelIndex on failure.
|
||||
BookingId GetMatchingHotelId(FeatureBuilder1 const & fb) const;
|
||||
/// @return true if |fb| is a hotel with a name.
|
||||
bool CanBeBooking(FeatureBuilder1 const & fb) const;
|
||||
|
||||
inline size_t Size() const { return m_hotels.size(); }
|
||||
Hotel const & GetHotelById(uint32_t id) const;
|
||||
Hotel & GetHotelById(uint32_t id);
|
||||
vector<uint32_t> GetNearestHotels(ms::LatLon const & latLon, size_t limit,
|
||||
double maxDistance = 0.0) const;
|
||||
Hotel const & GetHotelById(BookingId id) const;
|
||||
Hotel & GetHotelById(BookingId id);
|
||||
vector<BookingId> GetNearestHotels(ms::LatLon const & latLon, size_t limit,
|
||||
double maxDistance = 0.0) const;
|
||||
bool MatchByName(string const & osmName, vector<size_t> const & bookingIndexes) const;
|
||||
|
||||
void BuildHotels(function<void(FeatureBuilder1 &)> const & fn) const;
|
||||
|
||||
protected:
|
||||
map<uint32_t, Hotel> m_hotels;
|
||||
map<BookingId, Hotel> m_hotels;
|
||||
|
||||
using TPoint = boost::geometry::model::point<float, 2, boost::geometry::cs::cartesian>;
|
||||
using TBox = boost::geometry::model::box<TPoint>;
|
||||
using TValue = pair<TBox, uint32_t>;
|
||||
using TValue = pair<TBox, BookingId>;
|
||||
|
||||
// Create the rtree using default constructor.
|
||||
boost::geometry::index::rtree<TValue, boost::geometry::index::quadratic<16>> m_rtree;
|
||||
|
@ -108,9 +111,11 @@ protected:
|
|||
void BuildHotel(Hotel const & hotel, function<void(FeatureBuilder1 &)> const & fn) const;
|
||||
|
||||
void LoadHotels(istream & path, string const & addressReferencePath);
|
||||
/// @return an index of a matched hotel or numeric_limits<size_t>::max() on failure.
|
||||
size_t MatchWithBooking(FeatureBuilder1 const & e) const;
|
||||
/// @return an id of a matched hotel or kInvalidHotelIndex on failure.
|
||||
BookingId MatchWithBooking(FeatureBuilder1 const & e) const;
|
||||
};
|
||||
|
||||
ostream & operator<<(ostream & s, BookingDataset::Hotel const & h);
|
||||
|
||||
NEWTYPE_SIMPLE_OUTPUT(BookingDataset::BookingId);
|
||||
} // namespace generator
|
||||
|
|
|
@ -139,10 +139,11 @@ feature::GenerateInfo GetGenerateInfo()
|
|||
struct SampleItem
|
||||
{
|
||||
enum MatchStatus {Uninitialized, Yes, No};
|
||||
using BookingId = BookingDataset::BookingID;
|
||||
|
||||
SampleItem() = default;
|
||||
|
||||
SampleItem(osm::Id const & osmId, uint32_t const bookingId, MatchStatus const match = Uninitialized)
|
||||
SampleItem(osm::Id const & osmId, BookingId const bookingId, MatchStatus const match = Uninitialized)
|
||||
: m_osmId(osmId)
|
||||
, m_bookingId(bookingId)
|
||||
, m_match(match)
|
||||
|
@ -150,7 +151,7 @@ struct SampleItem
|
|||
}
|
||||
|
||||
osm::Id m_osmId;
|
||||
uint32_t m_bookingId = BookingDataset::kInvalidHotelIndex;
|
||||
BookingId m_bookingId = BookingDataset::kInvalidHotelIndex;
|
||||
|
||||
MatchStatus m_match = Uninitialized;
|
||||
};
|
||||
|
|
|
@ -342,8 +342,6 @@ public:
|
|||
static uint32_t const placeType = classif().GetTypeByPath({"place"});
|
||||
uint32_t const type = fb.GetParams().FindType(placeType, 1);
|
||||
|
||||
auto hotelIndex = generator::BookingDataset::kInvalidHotelIndex;
|
||||
|
||||
if (type != ftype::GetEmptyValue() && !fb.GetName().empty())
|
||||
{
|
||||
m_places.ReplaceEqualInRect(
|
||||
|
@ -351,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 ((hotelIndex = m_bookingDataset.GetMatchingHotelIndex(fb)) !=
|
||||
else if (m_bookingDataset.GetMatchingHotelId(fb) !=
|
||||
generator::BookingDataset::kInvalidHotelIndex)
|
||||
{
|
||||
m_skippedElements << DebugPrint(fb.GetMostGenericOsmId()) << endl;
|
||||
|
|
Loading…
Add table
Reference in a new issue