[generator] Review fixes in c++ part

This commit is contained in:
Sergey Yershov 2016-05-26 19:11:11 +03:00
parent 1c92e00abd
commit 01d9b2bb1b
3 changed files with 196 additions and 177 deletions

View file

@ -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);
}

View file

@ -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

View file

@ -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);