forked from organicmaps/organicmaps
[generator] Review fixes in c++ part
This commit is contained in:
parent
1c92e00abd
commit
01d9b2bb1b
3 changed files with 196 additions and 177 deletions
|
@ -42,30 +42,31 @@ UniChar LastUniChar(string const & s)
|
|||
return *iter;
|
||||
}
|
||||
|
||||
bool to_int(char const * s, int & i, int base /*= 10*/)
|
||||
namespace
|
||||
{
|
||||
template<typename T, typename ET>
|
||||
bool IntegerCheck(T x, char const *stop, ET & out)
|
||||
{
|
||||
char * stop;
|
||||
long const x = strtol(s, &stop, base);
|
||||
if (*stop == 0)
|
||||
{
|
||||
i = static_cast<int>(x);
|
||||
ASSERT_EQUAL(static_cast<long>(i), x, ());
|
||||
out = static_cast<ET>(x);
|
||||
ASSERT_EQUAL(static_cast<T>(out), x, ());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
bool to_int(char const * s, int & i, int base /*= 10*/)
|
||||
{
|
||||
char * stop;
|
||||
return IntegerCheck(strtol(s, &stop, base), stop, i);
|
||||
}
|
||||
|
||||
bool to_uint(char const * s, unsigned int & i, int base /*= 10*/)
|
||||
{
|
||||
char * stop;
|
||||
long const x = strtoul(s, &stop, base);
|
||||
if (*stop == 0)
|
||||
{
|
||||
i = static_cast<unsigned int>(x);
|
||||
ASSERT_EQUAL(static_cast<unsigned long>(i), x, ());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return IntegerCheck(strtoul(s, &stop, base), stop, i);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -13,6 +13,21 @@
|
|||
|
||||
namespace generator
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
bool CheckForValues(string const & value)
|
||||
{
|
||||
for (char const * val :
|
||||
{"hotel", "apartment", "camp_site", "chalet", "guest_house", "hostel", "motel", "resort"})
|
||||
{
|
||||
if (value == val)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
BookingDataset::Hotel::Hotel(string const & src)
|
||||
{
|
||||
vector<string> rec(FieldsCount());
|
||||
|
@ -42,22 +57,10 @@ ostream & operator<<(ostream & s, BookingDataset::Hotel const & h)
|
|||
return s << "Name: " << h.name << "\t Address: " << h.address << "\t lat: " << h.lat << " lon: " << h.lon;
|
||||
}
|
||||
|
||||
void BookingDataset::LoadHotels(string const & path)
|
||||
{
|
||||
m_hotels.clear();
|
||||
|
||||
if (path.empty())
|
||||
return;
|
||||
|
||||
ifstream src(path);
|
||||
for (string line; getline(src, line);)
|
||||
m_hotels.emplace_back(line);
|
||||
}
|
||||
|
||||
BookingDataset::BookingDataset(string const & dataPath)
|
||||
{
|
||||
LoadHotels(dataPath);
|
||||
|
||||
|
||||
size_t counter = 0;
|
||||
for (auto const & hotel : m_hotels)
|
||||
{
|
||||
|
@ -67,15 +70,166 @@ BookingDataset::BookingDataset(string const & dataPath)
|
|||
}
|
||||
}
|
||||
|
||||
bool CheckForValues(string const & value)
|
||||
bool BookingDataset::BookingFilter(OsmElement const & e) const
|
||||
{
|
||||
return Filter(e, [&](OsmElement const & e){ return MatchWithBooking(e); });
|
||||
}
|
||||
|
||||
bool BookingDataset::TourismFilter(OsmElement const & e) const
|
||||
{
|
||||
return Filter(e, [&](OsmElement const & e){ return true; });
|
||||
}
|
||||
|
||||
BookingDataset::Hotel const & BookingDataset::GetHotel(size_t index) const
|
||||
{
|
||||
ASSERT_GREATER(m_hotels.size(), index, ());
|
||||
return m_hotels[index];
|
||||
}
|
||||
|
||||
vector<size_t> BookingDataset::GetNearestHotels(double lat, double lon, size_t limit,
|
||||
double maxDistance /* = 0.0 */) const
|
||||
{
|
||||
namespace bgi = boost::geometry::index;
|
||||
|
||||
vector<size_t> indexes;
|
||||
for_each(bgi::qbegin(m_rtree, bgi::nearest(TPoint(lat, lon), limit)), bgi::qend(m_rtree),
|
||||
[&](TValue const & v)
|
||||
{
|
||||
auto const & hotel = m_hotels[v.second];
|
||||
double const dist = ms::DistanceOnEarth(lat, lon, hotel.lat, hotel.lon);
|
||||
if (maxDistance != 0.0 && dist > maxDistance /* max distance in meters */)
|
||||
return;
|
||||
|
||||
indexes.emplace_back(v.second);
|
||||
});
|
||||
return indexes;
|
||||
}
|
||||
|
||||
bool BookingDataset::MatchByName(string const & osmName, vector<size_t> const & bookingIndexes) const
|
||||
{
|
||||
for (char const * val :
|
||||
{"hotel", "apartment", "camp_site", "chalet", "guest_house", "hostel", "motel", "resort"})
|
||||
{
|
||||
if (value == val)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
// Match name.
|
||||
// vector<strings::UniString> osmTokens;
|
||||
// NormalizeAndTokenizeString(name, osmTokens, search::Delimiters());
|
||||
//
|
||||
// cout << "\n------------- " << name << endl;
|
||||
//
|
||||
// bool matched = false;
|
||||
// for (auto const & index : indexes)
|
||||
// {
|
||||
// vector<strings::UniString> bookingTokens;
|
||||
// NormalizeAndTokenizeString(m_hotels[index].name, bookingTokens, search::Delimiters());
|
||||
//
|
||||
// map<size_t, vector<pair<size_t, size_t>>> weightPair;
|
||||
//
|
||||
// for (size_t j = 0; j < osmTokens.size(); ++j)
|
||||
// {
|
||||
// for (size_t i = 0; i < bookingTokens.size(); ++i)
|
||||
// {
|
||||
// size_t distance = strings::EditDistance(osmTokens[j].begin(), osmTokens[j].end(),
|
||||
// bookingTokens[i].begin(), bookingTokens[i].end());
|
||||
// if (distance < 3)
|
||||
// weightPair[distance].emplace_back(i, j);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (!weightPair.empty())
|
||||
// {
|
||||
// cout << m_hotels[e.second] << endl;
|
||||
// matched = true;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
void BookingDataset::BuildFeatures(function<void(OsmElement *)> const & fn) const
|
||||
{
|
||||
for (auto const & hotel : m_hotels)
|
||||
{
|
||||
OsmElement e;
|
||||
e.type = OsmElement::EntityType::Node;
|
||||
e.id = 1;
|
||||
|
||||
e.lat = hotel.lat;
|
||||
e.lon = hotel.lon;
|
||||
|
||||
e.AddTag("name", hotel.name);
|
||||
e.AddTag("ref:sponsored", strings::to_string(hotel.id));
|
||||
e.AddTag("website", hotel.descUrl);
|
||||
e.AddTag("rating:sponsored", strings::to_string(hotel.ratingUser));
|
||||
e.AddTag("stars", strings::to_string(hotel.stars));
|
||||
e.AddTag("price_rate", strings::to_string(hotel.priceCategory));
|
||||
e.AddTag("addr:full", hotel.address);
|
||||
|
||||
switch (hotel.type)
|
||||
{
|
||||
case 19:
|
||||
case 205: e.AddTag("tourism", "motel"); break;
|
||||
|
||||
case 21:
|
||||
case 206:
|
||||
case 212: e.AddTag("tourism", "resort"); break;
|
||||
|
||||
case 3:
|
||||
case 23:
|
||||
case 24:
|
||||
case 25:
|
||||
case 202:
|
||||
case 207:
|
||||
case 208:
|
||||
case 209:
|
||||
case 210:
|
||||
case 216:
|
||||
case 220:
|
||||
case 223: e.AddTag("tourism", "guest_house"); break;
|
||||
|
||||
case 14:
|
||||
case 204:
|
||||
case 213:
|
||||
case 218:
|
||||
case 219:
|
||||
case 226:
|
||||
case 222: e.AddTag("tourism", "hotel"); break;
|
||||
|
||||
case 211:
|
||||
case 224:
|
||||
case 228: e.AddTag("tourism", "chalet"); break;
|
||||
|
||||
case 13:
|
||||
case 225:
|
||||
case 203: e.AddTag("tourism", "hostel"); break;
|
||||
|
||||
case 215:
|
||||
case 221:
|
||||
case 227:
|
||||
case 2:
|
||||
case 201: e.AddTag("tourism", "apartment"); break;
|
||||
|
||||
case 214: e.AddTag("tourism", "camp_site"); break;
|
||||
|
||||
default: e.AddTag("tourism", "hotel"); break;
|
||||
}
|
||||
|
||||
fn(&e);
|
||||
}
|
||||
}
|
||||
|
||||
void BookingDataset::LoadHotels(string const & path)
|
||||
{
|
||||
m_hotels.clear();
|
||||
|
||||
if (path.empty())
|
||||
return;
|
||||
|
||||
ifstream src(path);
|
||||
if (!src.is_open())
|
||||
{
|
||||
LOG(LERROR, ("Error while opening", path, ":", strerror(errno)));
|
||||
return;
|
||||
}
|
||||
|
||||
for (string line; getline(src, line);)
|
||||
m_hotels.emplace_back(line);
|
||||
}
|
||||
|
||||
bool BookingDataset::MatchWithBooking(OsmElement const & e) const
|
||||
|
@ -89,84 +243,19 @@ bool BookingDataset::MatchWithBooking(OsmElement const & e) const
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (name.empty())
|
||||
return false;
|
||||
|
||||
|
||||
// Find 3 nearest values to a point.
|
||||
auto const indexes = GetNearestHotels(e.lat, e.lon, 3, 150 /* max distance in meters */);
|
||||
if (indexes.empty())
|
||||
return false;
|
||||
|
||||
// Match name.
|
||||
vector<strings::UniString> osmTokens;
|
||||
NormalizeAndTokenizeString(name, osmTokens, search::Delimiters());
|
||||
|
||||
// cout << "\n------------- " << name << endl;
|
||||
|
||||
bool matched = false;
|
||||
for (auto const & index : indexes)
|
||||
{
|
||||
vector<strings::UniString> bookingTokens;
|
||||
NormalizeAndTokenizeString(m_hotels[index].name, bookingTokens, search::Delimiters());
|
||||
|
||||
map<size_t, vector<pair<size_t, size_t>>> weightPair;
|
||||
|
||||
for (size_t j = 0; j < osmTokens.size(); ++j)
|
||||
{
|
||||
for (size_t i = 0; i < bookingTokens.size(); ++i)
|
||||
{
|
||||
size_t distance = strings::EditDistance(osmTokens[j].begin(), osmTokens[j].end(),
|
||||
bookingTokens[i].begin(), bookingTokens[i].end());
|
||||
if (distance < 3)
|
||||
weightPair[distance].emplace_back(i, j);
|
||||
}
|
||||
}
|
||||
|
||||
if (!weightPair.empty())
|
||||
{
|
||||
// cout << m_hotels[e.second] << endl;
|
||||
matched = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool matched = MatchByName(name, indexes);
|
||||
return matched;
|
||||
}
|
||||
|
||||
BookingDataset::Hotel const & BookingDataset::GetHotel(size_t index) const
|
||||
{
|
||||
ASSERT_GREATER(m_hotels.size(), index, ());
|
||||
return m_hotels[index];
|
||||
}
|
||||
|
||||
vector<size_t> BookingDataset::GetNearestHotels(double lat, double lon, size_t limit,
|
||||
double maxDistance /* = 0.0 */) const
|
||||
{
|
||||
namespace bgi = boost::geometry::index;
|
||||
|
||||
vector<size_t> indexes;
|
||||
for_each(bgi::qbegin(m_rtree, bgi::nearest(TPoint(lat, lon), limit)), bgi::qend(m_rtree),
|
||||
[&](TValue const & v)
|
||||
{
|
||||
auto const & hotel = m_hotels[v.second];
|
||||
double const dist = ms::DistanceOnEarth(lat, lon, hotel.lat, hotel.lon);
|
||||
if (maxDistance != 0.0 && dist > maxDistance /* max distance in meters */)
|
||||
return;
|
||||
|
||||
indexes.emplace_back(v.second);
|
||||
});
|
||||
return indexes;
|
||||
}
|
||||
|
||||
bool BookingDataset::BookingFilter(OsmElement const & e) const
|
||||
{
|
||||
return Filter(e, [&](OsmElement const & e){ return MatchWithBooking(e); });
|
||||
}
|
||||
|
||||
bool BookingDataset::TourismFilter(OsmElement const & e) const
|
||||
{
|
||||
return Filter(e, [&](OsmElement const & e){ return true; });
|
||||
}
|
||||
|
||||
bool BookingDataset::Filter(OsmElement const & e, function<bool(OsmElement const &)> const & fn) const
|
||||
{
|
||||
if (e.type != OsmElement::EntityType::Node)
|
||||
|
@ -190,76 +279,4 @@ bool BookingDataset::Filter(OsmElement const & e, function<bool(OsmElement const
|
|||
return matched;
|
||||
}
|
||||
|
||||
void BookingDataset::BuildFeatures(function<void(OsmElement *)> const & fn) const
|
||||
{
|
||||
for (auto const & hotel : m_hotels)
|
||||
{
|
||||
OsmElement e;
|
||||
e.type = OsmElement::EntityType::Node;
|
||||
e.id = 1;
|
||||
|
||||
e.lon = hotel.lon;
|
||||
e.lat = hotel.lat;
|
||||
|
||||
e.AddTag("name", hotel.name);
|
||||
e.AddTag("ref:sponsored", strings::to_string(hotel.id));
|
||||
e.AddTag("website", hotel.descUrl);
|
||||
e.AddTag("rating:sponsored", strings::to_string(hotel.ratingUser));
|
||||
e.AddTag("stars", strings::to_string(hotel.stars));
|
||||
e.AddTag("price_rate", strings::to_string(hotel.priceCategory));
|
||||
e.AddTag("addr:full", hotel.address);
|
||||
|
||||
switch (hotel.type)
|
||||
{
|
||||
case 19:
|
||||
case 205: e.AddTag("tourism", "motel"); break;
|
||||
|
||||
case 21:
|
||||
case 206:
|
||||
case 212: e.AddTag("tourism", "resort"); break;
|
||||
|
||||
case 3:
|
||||
case 23:
|
||||
case 24:
|
||||
case 25:
|
||||
case 202:
|
||||
case 207:
|
||||
case 208:
|
||||
case 209:
|
||||
case 210:
|
||||
case 216:
|
||||
case 220:
|
||||
case 223: e.AddTag("tourism", "guest_house"); break;
|
||||
|
||||
case 14:
|
||||
case 204:
|
||||
case 213:
|
||||
case 218:
|
||||
case 219:
|
||||
case 226:
|
||||
case 222: e.AddTag("tourism", "hotel"); break;
|
||||
|
||||
case 211:
|
||||
case 224:
|
||||
case 228: e.AddTag("tourism", "chalet"); break;
|
||||
|
||||
case 13:
|
||||
case 225:
|
||||
case 203: e.AddTag("tourism", "hostel"); break;
|
||||
|
||||
case 215:
|
||||
case 221:
|
||||
case 227:
|
||||
case 2:
|
||||
case 201: e.AddTag("tourism", "apartment"); break;
|
||||
|
||||
case 214: e.AddTag("tourism", "camp_site"); break;
|
||||
|
||||
default: e.AddTag("tourism", "hotel"); break;
|
||||
}
|
||||
|
||||
fn(&e);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace generator
|
||||
|
|
|
@ -55,11 +55,12 @@ public:
|
|||
|
||||
bool BookingFilter(OsmElement const & e) const;
|
||||
bool TourismFilter(OsmElement const & e) const;
|
||||
void BuildFeatures(function<void(OsmElement *)> const & fn) const;
|
||||
|
||||
Hotel const & GetHotel(size_t index) const;
|
||||
vector<size_t> GetNearestHotels(double lat, double lon, size_t limit, double maxDistance = 0.0) const;
|
||||
|
||||
bool MatchByName(string const & osmName, vector<size_t> const & bookingIndexes) const;
|
||||
|
||||
void BuildFeatures(function<void(OsmElement *)> const & fn) const;
|
||||
protected:
|
||||
vector<Hotel> m_hotels;
|
||||
|
||||
|
@ -71,8 +72,8 @@ protected:
|
|||
boost::geometry::index::rtree<TValue, boost::geometry::index::quadratic<16>> m_rtree;
|
||||
|
||||
void LoadHotels(string const & path);
|
||||
bool Filter(OsmElement const & e, function<bool(OsmElement const &)> const & fn) const;
|
||||
bool MatchWithBooking(OsmElement const & e) const;
|
||||
bool Filter(OsmElement const & e, function<bool(OsmElement const &)> const & fn) const;
|
||||
};
|
||||
|
||||
ostream & operator<<(ostream & s, BookingDataset::Hotel const & h);
|
||||
|
|
Loading…
Add table
Reference in a new issue