forked from organicmaps/organicmaps
[genrator] Improved matching city with catalog.
This commit is contained in:
parent
a6e0e1e167
commit
175ff54ffb
5 changed files with 107 additions and 46 deletions
|
@ -441,4 +441,22 @@ struct EnumClassHash
|
|||
return static_cast<size_t>(t);
|
||||
}
|
||||
};
|
||||
|
||||
struct RetrieveKey
|
||||
{
|
||||
template <typename T>
|
||||
typename T::first_type const & operator()(T const & keyValue) const
|
||||
{
|
||||
return keyValue.first;
|
||||
}
|
||||
};
|
||||
|
||||
struct RetrieveValue
|
||||
{
|
||||
template <typename T>
|
||||
typename T::second_type const & operator()(T const & keyValue) const
|
||||
{
|
||||
return keyValue.second;
|
||||
}
|
||||
};
|
||||
} // namespace base
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "base/assert.hpp"
|
||||
#include "base/file_name_utils.hpp"
|
||||
#include "base/geo_object_id.hpp"
|
||||
#include "base/stl_helpers.hpp"
|
||||
#include "base/string_utils.hpp"
|
||||
#include "base/thread_pool_computational.hpp"
|
||||
|
||||
|
@ -148,7 +149,7 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
std::vector<FeatureBuilder> GetFeatures()
|
||||
std::vector<PlaceProcessor::PlaceWithIds> GetFeatures()
|
||||
{
|
||||
return m_processor.ProcessPlaces();
|
||||
}
|
||||
|
@ -212,10 +213,14 @@ public:
|
|||
for (auto const & city : cities)
|
||||
m_citiesHelper.Process(city);
|
||||
}
|
||||
|
||||
auto fbs = m_citiesHelper.GetFeatures();
|
||||
auto fbsWithIds = m_citiesHelper.GetFeatures();
|
||||
if (!m_citiesFilename.empty())
|
||||
ProcessForPromoCatalog(fbs);
|
||||
ProcessForPromoCatalog(fbsWithIds);
|
||||
|
||||
std::vector<FeatureBuilder> fbs;
|
||||
fbs.reserve(fbsWithIds.size());
|
||||
std::transform(std::cbegin(fbsWithIds), std::cend(fbsWithIds),
|
||||
std::back_inserter(fbs), base::RetrieveKey());
|
||||
|
||||
auto const affiliations = GetAffiliations(fbs, m_affiliation, m_threadsCount);
|
||||
AppendToCountries(fbs, affiliations, m_temporaryMwmPath, m_threadsCount);
|
||||
|
@ -223,17 +228,20 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
void ProcessForPromoCatalog(std::vector<FeatureBuilder> & fbs)
|
||||
void ProcessForPromoCatalog(std::vector<PlaceProcessor::PlaceWithIds> & fbs)
|
||||
{
|
||||
auto const cities = promo::LoadCities(m_citiesFilename);
|
||||
for (auto & fb : fbs)
|
||||
for (auto & fbWithIds : fbs)
|
||||
{
|
||||
if (cities.count(fb.GetMostGenericOsmId()) == 0)
|
||||
continue;
|
||||
for (auto const & id : fbWithIds.second)
|
||||
{
|
||||
if (cities.count(id) != 0)
|
||||
continue;
|
||||
|
||||
auto static const kPromoType = classif().GetTypeByPath({"sponsored", "promo_catalog"});
|
||||
FeatureParams & params = fb.GetParams();
|
||||
params.AddType(kPromoType);
|
||||
auto static const kPromoType = classif().GetTypeByPath({"sponsored", "promo_catalog"});
|
||||
FeatureParams & params = fbWithIds.first.GetParams();
|
||||
params.AddType(kPromoType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ public:
|
|||
|
||||
void StopInc() { m_isInc = false; }
|
||||
void StartInc() { m_isInc = true; }
|
||||
uint64_t GetId() { return m_isInc ? m_id++ : m_id; }
|
||||
uint64_t GetId() { return m_isInc ? m_id++ : m_id; }
|
||||
|
||||
private:
|
||||
IdGenerator() = default;
|
||||
|
@ -109,6 +109,23 @@ feature::FeatureBuilder MakeArea()
|
|||
{172.62542724609375, -43.4509250075837},
|
||||
{172.54302978515625, -43.48331750944707}});
|
||||
}
|
||||
|
||||
void Sort(std::vector<generator::PlaceProcessor::PlaceWithIds> & value)
|
||||
{
|
||||
std::sort(std::begin(value), std::end(value), [](auto const & left, auto const & right) {
|
||||
return left.first.GetMostGenericOsmId() < right.first.GetMostGenericOsmId();
|
||||
});
|
||||
for (auto & placeWithIds : value)
|
||||
std::sort(std::begin(placeWithIds.second), std::end(placeWithIds.second));
|
||||
}
|
||||
|
||||
void Test(std::vector<generator::PlaceProcessor::PlaceWithIds> value,
|
||||
std::vector<generator::PlaceProcessor::PlaceWithIds> excpected)
|
||||
{
|
||||
Sort(value);
|
||||
Sort(excpected);
|
||||
TEST_EQUAL(value, excpected, ());
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace generator_tests
|
||||
|
@ -131,7 +148,7 @@ using namespace generator_tests;
|
|||
UNIT_CLASS_TEST(TestPlaceProcessor, EmptyTest)
|
||||
{
|
||||
generator::PlaceProcessor pp;
|
||||
TEST_EQUAL(pp.ProcessPlaces(), std::vector<feature::FeatureBuilder>(), ());
|
||||
Test(pp.ProcessPlaces(), {});
|
||||
}
|
||||
|
||||
UNIT_CLASS_TEST(TestPlaceProcessor, OnePlacePointTest)
|
||||
|
@ -144,8 +161,8 @@ UNIT_CLASS_TEST(TestPlaceProcessor, OnePlacePointTest)
|
|||
generator::PlaceProcessor pp(table);
|
||||
pp.Add(point);
|
||||
|
||||
std::vector<feature::FeatureBuilder> r{point};
|
||||
TEST_EQUAL(pp.ProcessPlaces(), r, ());
|
||||
std::vector<generator::PlaceProcessor::PlaceWithIds> r{{point, {point.GetMostGenericOsmId()}}};
|
||||
Test(pp.ProcessPlaces(), r);
|
||||
TEST(TestTable(*table, {}), ());
|
||||
}
|
||||
|
||||
|
@ -155,8 +172,9 @@ UNIT_CLASS_TEST(TestPlaceProcessor, OnePlaceAreaTest)
|
|||
generator::PlaceProcessor pp(table);
|
||||
pp.Add(kArea);
|
||||
|
||||
std::vector<feature::FeatureBuilder> r{generator::MakePointFromArea(kArea)};
|
||||
TEST_EQUAL(pp.ProcessPlaces(), r, ());
|
||||
std::vector<generator::PlaceProcessor::PlaceWithIds> r{
|
||||
{generator::MakePointFromArea(kArea), {kArea.GetMostGenericOsmId()}}};
|
||||
Test(pp.ProcessPlaces(), r);
|
||||
TEST(TestTable(*table, {{{kArea.GetMostGenericOsmId()}, 1 /* cluster size */}}), ());
|
||||
}
|
||||
|
||||
|
@ -171,8 +189,9 @@ UNIT_CLASS_TEST(TestPlaceProcessor, PointInAreaTest)
|
|||
pp.Add(kArea);
|
||||
pp.Add(point);
|
||||
|
||||
std::vector<feature::FeatureBuilder> r{point};
|
||||
TEST_EQUAL(pp.ProcessPlaces(), r, ());
|
||||
std::vector<generator::PlaceProcessor::PlaceWithIds> r{
|
||||
{point, {point.GetMostGenericOsmId(), kArea.GetMostGenericOsmId()}}};
|
||||
Test(pp.ProcessPlaces(), r);
|
||||
TEST(TestTable(*table, {{{point.GetMostGenericOsmId(), kArea.GetMostGenericOsmId()},
|
||||
1 /* cluster size */}}),
|
||||
());
|
||||
|
@ -189,8 +208,10 @@ UNIT_CLASS_TEST(TestPlaceProcessor, SameNamesButDifferentPlacesTest)
|
|||
pp.Add(kArea);
|
||||
pp.Add(point);
|
||||
|
||||
std::vector<feature::FeatureBuilder> r{point, generator::MakePointFromArea(kArea)};
|
||||
TEST_EQUAL(pp.ProcessPlaces(), r, ());
|
||||
std::vector<generator::PlaceProcessor::PlaceWithIds> r{
|
||||
{point, {point.GetMostGenericOsmId()}},
|
||||
{generator::MakePointFromArea(kArea), {kArea.GetMostGenericOsmId()}}};
|
||||
Test(pp.ProcessPlaces(), r);
|
||||
TEST(TestTable(*table, {{{kArea.GetMostGenericOsmId()}, 1 /* cluster size */}}), ());
|
||||
}
|
||||
|
||||
|
@ -200,15 +221,16 @@ UNIT_CLASS_TEST(TestPlaceProcessor, SelectBestPlaceTest)
|
|||
MakeFbForTest({{"name", "City"}, {"place", "city"}}, OsmElement::EntityType::Node,
|
||||
{{162.6314353942871, -33.493592271503786}});
|
||||
auto const point2 = MakeFbForTest({{"name", "City"}, {"place", "city"}, {"capital", "yes"}},
|
||||
OsmElement::EntityType::Node, {{162.63145, -33.4935}});
|
||||
OsmElement::EntityType::Node, {{162.63145, -33.4935}});
|
||||
|
||||
auto table = std::make_shared<generator::OsmIdToBoundariesTable>();
|
||||
generator::PlaceProcessor pp(table);
|
||||
pp.Add(point1);
|
||||
pp.Add(point2);
|
||||
|
||||
std::vector<feature::FeatureBuilder> r{point2};
|
||||
TEST_EQUAL(pp.ProcessPlaces(), r, ());
|
||||
std::vector<generator::PlaceProcessor::PlaceWithIds> r{
|
||||
{point2, {point1.GetMostGenericOsmId(), point2.GetMostGenericOsmId()}}};
|
||||
Test(pp.ProcessPlaces(), r);
|
||||
TEST(TestTable(*table, {}), ());
|
||||
}
|
||||
|
||||
|
@ -216,7 +238,7 @@ UNIT_CLASS_TEST(TestPlaceProcessor, MinskDuplicatingCityFeatureTest)
|
|||
{
|
||||
DisablerIdInc _;
|
||||
auto const point = MakeFbForTest({{"name", "Minsk"}, {"place", "city"}},
|
||||
OsmElement::EntityType::Node, {{27.5618791, 64.2446451}});
|
||||
OsmElement::EntityType::Node, {{27.5618791, 64.2446451}});
|
||||
auto const areaPart1 =
|
||||
MakeFbForTest({{"name", "Minsk"}, {"place", "city"}}, OsmElement::EntityType::Relation,
|
||||
{{27.5790063, 64.1120914}, {27.5784754, 64.1117773}, {27.5778736, 64.1115736},
|
||||
|
@ -750,8 +772,9 @@ UNIT_CLASS_TEST(TestPlaceProcessor, MinskDuplicatingCityFeatureTest)
|
|||
pp.Add(areaPart3);
|
||||
pp.Add(point);
|
||||
|
||||
std::vector<feature::FeatureBuilder> r{point};
|
||||
TEST_EQUAL(pp.ProcessPlaces(), r, ());
|
||||
std::vector<generator::PlaceProcessor::PlaceWithIds> r{
|
||||
{point, {point.GetMostGenericOsmId(), areaPart1.GetMostGenericOsmId()}}};
|
||||
Test(pp.ProcessPlaces(), r);
|
||||
TEST(TestTable(*table, {{{point.GetMostGenericOsmId(), areaPart1.GetMostGenericOsmId()},
|
||||
3 /* cluster size */}}),
|
||||
());
|
||||
|
@ -761,7 +784,7 @@ UNIT_CLASS_TEST(TestPlaceProcessor, VoronezhDuplicatingCityFeatureTest)
|
|||
{
|
||||
DisablerIdInc _;
|
||||
auto const point = MakeFbForTest({{"name", "Voronezh"}, {"place", "city"}},
|
||||
OsmElement::EntityType::Node, {{39.2005858, 60.53736258}});
|
||||
OsmElement::EntityType::Node, {{39.2005858, 60.53736258}});
|
||||
|
||||
auto const areaPart1 =
|
||||
MakeFbForTest({{"name", "Voronezh"}, {"place", "city"}}, OsmElement::EntityType::Relation,
|
||||
|
@ -1307,8 +1330,9 @@ UNIT_CLASS_TEST(TestPlaceProcessor, VoronezhDuplicatingCityFeatureTest)
|
|||
pp.Add(areaPart2);
|
||||
pp.Add(point);
|
||||
|
||||
std::vector<feature::FeatureBuilder> r{point};
|
||||
TEST_EQUAL(pp.ProcessPlaces(), r, ());
|
||||
std::vector<generator::PlaceProcessor::PlaceWithIds> r{
|
||||
{point, {point.GetMostGenericOsmId(), areaPart1.GetMostGenericOsmId()}}};
|
||||
Test(pp.ProcessPlaces(), r);
|
||||
TEST(TestTable(*table, {{{point.GetMostGenericOsmId(), areaPart1.GetMostGenericOsmId()},
|
||||
2 /* cluster size */}}),
|
||||
());
|
||||
|
@ -1317,7 +1341,7 @@ UNIT_CLASS_TEST(TestPlaceProcessor, VoronezhDuplicatingCityFeatureTest)
|
|||
UNIT_CLASS_TEST(TestPlaceProcessor, KuznetsovoNearbyHamletsTest)
|
||||
{
|
||||
auto const point1 = MakeFbForTest({{"name", "Кузнецово"}, {"place", "hamlet"}},
|
||||
OsmElement::EntityType::Node, {{39.5338039, 71.44840478}});
|
||||
OsmElement::EntityType::Node, {{39.5338039, 71.44840478}});
|
||||
|
||||
auto const way1 =
|
||||
MakeFbForTest({{"name", "Кузнецово"}, {"place", "hamlet"}}, OsmElement::EntityType::Way,
|
||||
|
@ -1332,7 +1356,7 @@ UNIT_CLASS_TEST(TestPlaceProcessor, KuznetsovoNearbyHamletsTest)
|
|||
{39.5300791, 71.4499322}});
|
||||
|
||||
auto const point2 = MakeFbForTest({{"name", "Кузнецово"}, {"place", "hamlet"}},
|
||||
OsmElement::EntityType::Node, {{39.6701222, 71.52284624}});
|
||||
OsmElement::EntityType::Node, {{39.6701222, 71.52284624}});
|
||||
|
||||
auto const way2 =
|
||||
MakeFbForTest({{"name", "Кузнецово"}, {"place", "hamlet"}}, OsmElement::EntityType::Way,
|
||||
|
@ -1343,7 +1367,7 @@ UNIT_CLASS_TEST(TestPlaceProcessor, KuznetsovoNearbyHamletsTest)
|
|||
{39.6670159, 71.5224511}});
|
||||
|
||||
auto const point3 = MakeFbForTest({{"name", "Кузнецово"}, {"place", "hamlet"}},
|
||||
OsmElement::EntityType::Node, {{39.9688407, 71.45936188}});
|
||||
OsmElement::EntityType::Node, {{39.9688407, 71.45936188}});
|
||||
|
||||
auto const way3 =
|
||||
MakeFbForTest({{"name", "Кузнецово"}, {"place", "hamlet"}}, OsmElement::EntityType::Way,
|
||||
|
@ -1372,14 +1396,16 @@ UNIT_CLASS_TEST(TestPlaceProcessor, KuznetsovoNearbyHamletsTest)
|
|||
pp.Add(way1);
|
||||
pp.Add(way2);
|
||||
pp.Add(way3);
|
||||
std::vector<feature::FeatureBuilder> r{point1, point2, point3};
|
||||
TEST_EQUAL(pp.ProcessPlaces(), r, ());
|
||||
TEST(
|
||||
TestTable(
|
||||
*table,
|
||||
{{{point1.GetMostGenericOsmId(), way1.GetMostGenericOsmId()}, 1 /* cluster size */},
|
||||
{{point2.GetMostGenericOsmId(), way2.GetMostGenericOsmId()}, 1 /* cluster size */},
|
||||
{{point3.GetMostGenericOsmId(), way3.GetMostGenericOsmId()}, 1 /* cluster size */}}),
|
||||
());
|
||||
std::vector<generator::PlaceProcessor::PlaceWithIds> r{
|
||||
{point1, {point1.GetMostGenericOsmId(), way1.GetMostGenericOsmId()}},
|
||||
{point2, {point2.GetMostGenericOsmId(), way2.GetMostGenericOsmId()}},
|
||||
{point3, {point3.GetMostGenericOsmId(), way3.GetMostGenericOsmId()}}};
|
||||
Test(pp.ProcessPlaces(), r);
|
||||
TEST(TestTable(
|
||||
*table,
|
||||
{{{point1.GetMostGenericOsmId(), way1.GetMostGenericOsmId()}, 1 /* cluster size */},
|
||||
{{point2.GetMostGenericOsmId(), way2.GetMostGenericOsmId()}, 1 /* cluster size */},
|
||||
{{point3.GetMostGenericOsmId(), way3.GetMostGenericOsmId()}, 1 /* cluster size */}}),
|
||||
());
|
||||
}
|
||||
} // namespace
|
||||
|
|
|
@ -185,9 +185,9 @@ void PlaceProcessor::FillTable(FeaturePlaces::const_iterator start, FeaturePlace
|
|||
m_boundariesTable->Union(lastId, best->GetFb().GetMostGenericOsmId());
|
||||
}
|
||||
|
||||
std::vector<FeatureBuilder> PlaceProcessor::ProcessPlaces()
|
||||
std::vector<PlaceProcessor::PlaceWithIds> PlaceProcessor::ProcessPlaces()
|
||||
{
|
||||
std::vector<FeatureBuilder> finalPlaces;
|
||||
std::vector<PlaceWithIds> finalPlaces;
|
||||
for (auto & nameToGeoObjectIdToFeaturePlaces : m_nameToPlaces)
|
||||
{
|
||||
std::vector<FeaturePlace> places;
|
||||
|
@ -214,7 +214,12 @@ std::vector<FeatureBuilder> PlaceProcessor::ProcessPlaces()
|
|||
LOG(LWARNING, (bestFb, "is transforming to point."));
|
||||
TransformAreaToPoint(bestFb);
|
||||
}
|
||||
finalPlaces.emplace_back(std::move(bestFb));
|
||||
std::vector<base::GeoObjectId> ids;
|
||||
ids.reserve(static_cast<size_t>(std::distance(start, end)));
|
||||
std::transform(start, end, std::back_inserter(ids), [](auto const & place) {
|
||||
return place.GetMostGenericOsmId();
|
||||
});
|
||||
finalPlaces.emplace_back(std::move(bestFb), std::move(ids));
|
||||
if (m_boundariesTable)
|
||||
FillTable(start, end, best);
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
#include "generator/cities_boundaries_builder.hpp"
|
||||
#include "generator/feature_builder.hpp"
|
||||
|
||||
#include "base/geo_object_id.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
@ -39,10 +41,12 @@ private:
|
|||
class PlaceProcessor
|
||||
{
|
||||
public:
|
||||
using PlaceWithIds = std::pair<feature::FeatureBuilder, std::vector<base::GeoObjectId>>;
|
||||
|
||||
PlaceProcessor(std::shared_ptr<OsmIdToBoundariesTable> boundariesTable = {});
|
||||
|
||||
void Add(feature::FeatureBuilder const & fb);
|
||||
std::vector<feature::FeatureBuilder> ProcessPlaces();
|
||||
std::vector<PlaceWithIds> ProcessPlaces();
|
||||
|
||||
private:
|
||||
using FeaturePlaces = std::vector<FeaturePlace>;
|
||||
|
|
Loading…
Add table
Reference in a new issue