diff --git a/generator/CMakeLists.txt b/generator/CMakeLists.txt index 6975bfde92..143e835de8 100644 --- a/generator/CMakeLists.txt +++ b/generator/CMakeLists.txt @@ -120,8 +120,6 @@ set( platform_helpers.hpp popular_places_section_builder.cpp popular_places_section_builder.hpp - popularity.cpp - popularity.hpp processor_booking.hpp processor_coastline.cpp processor_coastline.hpp diff --git a/generator/generator_tests/CMakeLists.txt b/generator/generator_tests/CMakeLists.txt index 6f4e37d47e..de55173a0d 100644 --- a/generator/generator_tests/CMakeLists.txt +++ b/generator/generator_tests/CMakeLists.txt @@ -28,7 +28,6 @@ set( osm_o5m_source_test.cpp osm_type_test.cpp place_processor_tests.cpp - popularity_builder_tests.cpp restriction_collector_test.cpp restriction_test.cpp road_access_test.cpp diff --git a/generator/generator_tests/popularity_builder_tests.cpp b/generator/generator_tests/popularity_builder_tests.cpp deleted file mode 100644 index 4c0ce70900..0000000000 --- a/generator/generator_tests/popularity_builder_tests.cpp +++ /dev/null @@ -1,455 +0,0 @@ -#include "testing/testing.hpp" - -#include "generator/feature_generator.hpp" -#include "generator/generator_tests/common.hpp" -#include "generator/popularity.hpp" - -#include "indexer/classificator_loader.hpp" -#include "indexer/classificator.hpp" - -#include "platform/platform.hpp" - -#include "coding/string_utf8_multilang.hpp" - -#include "base/geo_object_id.hpp" -#include "base/scope_guard.hpp" - -#include -#include -#include -#include -#include -#include - -using namespace generator; -using namespace generator::popularity; -using namespace feature; - -namespace generator_tests -{ -class TestPopularityBuilder -{ -public: - TestPopularityBuilder() - { - classificator::Load(); - m_testSet = TestPopularityBuilder::GetTestSet(); - } - - void GetType() const - { - { - FeatureBuilder fb; - auto const type = m_cl.GetTypeByPath({"tourism", "museum"}); - auto const checkableType = m_cl.GetReadableObjectName(type); - fb.AddType(m_cl.GetTypeByPath({"building"})); - fb.AddType(type); - TEST_EQUAL(PopularityBuilder::GetType(fb), checkableType, ()); - } - - { - FeatureBuilder fb; - fb.AddType(m_cl.GetTypeByPath({"building"})); - TEST_EQUAL(PopularityBuilder::GetType(fb), "", ()); - } - - { - FeatureBuilder fb; - TEST_EQUAL(PopularityBuilder::GetType(fb), "", ()); - } - } - - static void GetFeatureName() - { - { - FeatureBuilder fb; - std::string checkableName = "Фича"; - fb.AddName("ru", checkableName); - fb.AddName("en", "Feature"); - TEST_EQUAL(PopularityBuilder::GetFeatureName(fb), checkableName, ()); - } - - { - FeatureBuilder fb; - std::string checkableName = "Feature"; - fb.AddName("en", checkableName); - fb.AddName("default", "Fonctionnalité"); - TEST_EQUAL(PopularityBuilder::GetFeatureName(fb), checkableName, ()); - } - - { - FeatureBuilder fb; - std::string checkableName = "Fonctionnalité"; - fb.AddName("default", checkableName); - TEST_EQUAL(PopularityBuilder::GetFeatureName(fb), checkableName, ()); - } - - { - FeatureBuilder fb; - fb.AddName("fr", "Fonctionnalité"); - TEST_EQUAL(PopularityBuilder::GetFeatureName(fb), "", ()); - } - - { - FeatureBuilder fb; - TEST_EQUAL(PopularityBuilder::GetFeatureName(fb), "", ()); - } - } - - void FindPointParent() const - { - auto const filtered = FilterPoint(m_testSet); - std::map pointMap; - for (auto const & f : filtered) - pointMap.emplace(f.GetName(), f); - - auto const filteredArea = FilterArea(m_testSet); - auto geomPlaces = MakePopularityGeomPlaces(filteredArea); - auto const nameToNode = GetPlacesMap(geomPlaces); - auto const m = PopularityBuilder::GetAreaMap(geomPlaces); - auto const tree = PopularityBuilder::MakeTree4d(geomPlaces); - - { - auto const & ft = pointMap.at("1_3_4"); - auto const parent = PopularityBuilder::FindPointParent(ft.GetKeyPoint(), m, tree); - TEST(parent, ()); - TEST_EQUAL(*parent, nameToNode.at("1_3")->GetData().GetId(), ()); - } - - { - auto const & ft = pointMap.at("1_3_5"); - auto const parent = PopularityBuilder::FindPointParent(ft.GetKeyPoint(), m, tree); - TEST(parent, ()); - TEST_EQUAL(*parent, nameToNode.at("1_3")->GetData().GetId(), ()); - } - - { - m2::PointD bad{1000.0, 1000.0}; - auto const parent = PopularityBuilder::FindPointParent(bad, m, tree); - TEST(!parent, ()); - } - } - - void FindPopularityGeomPlaceParent() const - { - auto const filtered = FilterArea(m_testSet); - auto geomPlaces = MakePopularityGeomPlaces(filtered); - auto const nameToNode = GetPlacesMap(geomPlaces); - auto const m = PopularityBuilder::GetAreaMap(geomPlaces); - auto const tree = PopularityBuilder::MakeTree4d(geomPlaces); - - { - auto const t = PopularityBuilder::FindPopularityGeomPlaceParent(nameToNode.at("1_2")->GetData(), m, tree); - TEST(t, ()); - TEST_EQUAL(*t, nameToNode.at("1"), ()); - } - - { - auto const t = PopularityBuilder::FindPopularityGeomPlaceParent(nameToNode.at("1_3")->GetData(), m, tree); - TEST(t, ()); - TEST_EQUAL(*t, nameToNode.at("1"), ()); - } - - { - auto const t = PopularityBuilder::FindPopularityGeomPlaceParent(nameToNode.at("1")->GetData(), m, tree); - TEST(!t, ()); - } - } - - void GetAreaMap() const - { - { - auto const filtered = FilterArea(m_testSet); - auto const geomPlaces = MakePopularityGeomPlaces(filtered); - std::map checkableMap; - for (auto const & n : geomPlaces) - checkableMap.emplace(n->GetData().GetId(), n); - - auto const m = PopularityBuilder::GetAreaMap(geomPlaces); - TEST_EQUAL(m.size(), checkableMap.size(), ()); - for (auto const & p : checkableMap) - { - TEST_EQUAL(m.count(p.first), 1, ()); - TEST_EQUAL(p.second, m.at(p.first), ()); - } - } - - { - auto const m = PopularityBuilder::GetAreaMap({}); - TEST(m.empty(), ()); - } - } - - void MakeTree4d() const - { - { - std::set checkableIds; - auto const filtered = FilterArea(m_testSet); - auto const geomPlaces = MakePopularityGeomPlaces(filtered); - for (auto const & node : geomPlaces) - checkableIds.insert(node->GetData().GetId()); - - auto const tree = PopularityBuilder::MakeTree4d(geomPlaces); - std::set ids; - tree.ForEach([&](auto const & id) { - ids.insert(id); - }); - - TEST_EQUAL(checkableIds, ids, ()); - } - - { - std::set checkableIds; - auto const tree = PopularityBuilder::MakeTree4d({}); - std::set ids; - tree.ForEach([&](auto const & id) { - ids.insert(id); - }); - - TEST_EQUAL(checkableIds, ids, ()); - } - } - - void LinkGeomPlaces() const - { - auto const filtered = FilterArea(m_testSet); - auto geomPlaces = MakePopularityGeomPlaces(filtered); - auto const nameToNode = GetPlacesMap(geomPlaces); - auto const m = PopularityBuilder::GetAreaMap(geomPlaces); - auto const tree = PopularityBuilder::MakeTree4d(geomPlaces); - PopularityBuilder::LinkGeomPlaces(m, tree, geomPlaces); - - TEST_EQUAL(nameToNode.size(), 3, ()); - TEST_EQUAL(nameToNode.at("1")->GetParent(), PopularityBuilder::Node::Ptr(), ()); - TEST_EQUAL(nameToNode.at("1_2")->GetParent(), nameToNode.at("1"), ()); - TEST_EQUAL(nameToNode.at("1_3")->GetParent(), nameToNode.at("1"), ()); - } - - void MakeNodes() - { - std::vector v = FilterArea(m_testSet); - auto const nodes = PopularityBuilder::MakeNodes(v); - TEST_EQUAL(nodes.size(), v.size(), ()); - for (size_t i = 0; i < v.size(); ++i) - TEST_EQUAL(nodes[i]->GetData().GetId(), v[i].GetMostGenericOsmId() , ()); - } - - void Build() const - { - auto const filename = GetFileName(); - auto const type = m_cl.GetTypeByPath({"tourism", "museum"}); - auto const typeName = m_cl.GetReadableObjectName(type); - - { - FeaturesCollector collector(filename); - for (auto const & feature : m_testSet) - collector.Collect(feature); - } - - PopularityBuilder builder(filename); - auto const lines = builder.Build(); - - std::map m; - for (auto const & line : lines) - m.emplace(line.m_name, line); - - SCOPE_GUARD(RemoveFile, [&] { - Platform::RemoveFileIfExists(filename); - }); - - TEST_EQUAL(lines.size(), m_testSet.size(), ()); - TEST(!m.at("1").m_parent, ()); - TEST_EQUAL(m.at("1").m_type, typeName, ()); - - TEST(m.at("1_2").m_parent, ()); - TEST_EQUAL(*m.at("1_2").m_parent, m.at("1").m_id, ()); - TEST_EQUAL(m.at("1_2").m_type, typeName, ()); - - TEST(m.at("1_3").m_parent, ()); - TEST_EQUAL(*m.at("1_3").m_parent, m.at("1").m_id, ()); - TEST_EQUAL(m.at("1_3").m_type, typeName, ()); - - TEST(m.at("1_3_4").m_parent, ()); - TEST_EQUAL(*m.at("1_3_4").m_parent, m.at("1_3").m_id, ()); - TEST_EQUAL(m.at("1_3_4").m_type, typeName, ()); - - TEST(m.at("1_3_5").m_parent, ()); - TEST_EQUAL(*m.at("1_3_5").m_parent, m.at("1_3").m_id, ()); - TEST_EQUAL(m.at("1_3_5").m_type, typeName, ()); - } - -private: - static std::vector GetTestSet() - { - std::vector v; - v.reserve(5); - - { - FeatureBuilder feature; - feature.AddOsmId(base::GeoObjectId(1)); - auto const firstLast = m2::PointD{0.0, 0.0}; - feature.AddPoint(firstLast); - feature.AddPoint(m2::PointD{0.0, 7.0}); - feature.AddPoint(m2::PointD{10.0, 7.0}); - feature.AddPoint(m2::PointD{10.0, 0.0}); - feature.AddPoint(firstLast); - feature.SetArea(); - feature.AddType(classif().GetTypeByPath({"tourism", "museum"})); - feature.AddName("default", "1"); - v.push_back(feature); - } - - { - FeatureBuilder feature; - feature.AddOsmId(base::GeoObjectId(2)); - auto const firstLast = m2::PointD{2.0, 3.0}; - feature.AddPoint(firstLast); - feature.AddPoint(m2::PointD{2.0, 5.0}); - feature.AddPoint(m2::PointD{4.0, 5.0}); - feature.AddPoint(m2::PointD{4.0, 3.0}); - feature.AddPoint(firstLast); - feature.SetArea(); - feature.AddType(classif().GetTypeByPath({"tourism", "museum"})); - feature.AddName("default", "1_2"); - v.push_back(feature); - } - - { - FeatureBuilder feature; - feature.AddOsmId(base::GeoObjectId(3)); - auto const firstLast = m2::PointD{6.0, 0.0}; - feature.AddPoint(firstLast); - feature.AddPoint(m2::PointD{6.0, 3.0}); - feature.AddPoint(m2::PointD{10.0, 3.0}); - feature.AddPoint(m2::PointD{10.0, 0.0}); - feature.AddPoint(firstLast); - feature.SetArea(); - feature.AddType(classif().GetTypeByPath({"tourism", "museum"})); - feature.AddName("default", "1_3"); - v.push_back(feature); - } - - { - FeatureBuilder feature; - feature.AddOsmId(base::GeoObjectId(4)); - feature.SetCenter(m2::PointD{8.0, 2.0}); - feature.AddName("default", "1_3_4"); - feature.AddType(classif().GetTypeByPath({"tourism", "museum"})); - v.push_back(feature); - } - - { - FeatureBuilder feature; - feature.AddOsmId(base::GeoObjectId(5)); - feature.SetCenter(m2::PointD{7.0, 2.0}); - feature.AddName("default", "1_3_5"); - feature.AddType(classif().GetTypeByPath({"tourism", "museum"})); - v.push_back(feature); - } - - return v; - } - - static std::vector FilterArea(std::vector const & v) - { - std::vector filtered; - std::copy_if(std::begin(v), std::end(v), std::back_inserter(filtered), [](auto const & feature) { - return feature.IsArea() && feature.IsGeometryClosed(); - }); - - return filtered; - } - - static std::vector FilterPoint(std::vector const & v) - { - std::vector filtered; - std::copy_if(std::begin(v), std::end(v), std::back_inserter(filtered), [](auto const & feature) { - return feature.IsPoint(); - }); - - return filtered; - } - - static std::map - GetPlacesMap(PopularityBuilder::Node::PtrList const & geomPlaces) - { - std::map nameToNode; - for (auto const & place : geomPlaces) - nameToNode.emplace(place->GetData().GetFeature().GetName(), place); - - return nameToNode; - } - - static PopularityBuilder::Node::PtrList MakePopularityGeomPlaces(std::vector const & v) - { - PopularityBuilder::Node::PtrList nodes; - nodes.reserve(v.size()); - std::transform(std::begin(v), std::end(v), std::back_inserter(nodes), [](FeatureBuilder const & f) { - return std::make_shared(PopularityGeomPlace(f)); - }); - - return nodes; - } - - static std::vector AddTypes(std::vector v, std::vector const & types) - { - for (auto & feature : v) - { - for (auto const & type : types) - feature.AddType(type); - } - - return v; - } - - Classificator const & m_cl = classif(); - std::vector m_testSet; -}; -} // namespace generator_tests - -using namespace generator_tests; - -UNIT_CLASS_TEST(TestPopularityBuilder, PopularityBuilder_GetType) -{ - TestPopularityBuilder::GetType(); -} - -UNIT_CLASS_TEST(TestPopularityBuilder, PopularityBuilder_GetFeatureName) -{ - TestPopularityBuilder::GetFeatureName(); -} - -UNIT_CLASS_TEST(TestPopularityBuilder, PopularityBuilder_FindPointParent) -{ - TestPopularityBuilder::FindPointParent(); -} - -UNIT_CLASS_TEST(TestPopularityBuilder, PopularityBuilder_FindPopularityGeomPlaceParent) -{ - TestPopularityBuilder::FindPopularityGeomPlaceParent(); -} - -UNIT_CLASS_TEST(TestPopularityBuilder, PopularityBuilder_GetAreaMap) -{ - TestPopularityBuilder::GetAreaMap(); -} - -UNIT_CLASS_TEST(TestPopularityBuilder, PopularityBuilder_MakeTree4d) -{ - TestPopularityBuilder::MakeTree4d(); -} - -UNIT_CLASS_TEST(TestPopularityBuilder, PopularityBuilder_LinkGeomPlaces) -{ - TestPopularityBuilder::LinkGeomPlaces(); -} - -UNIT_CLASS_TEST(TestPopularityBuilder, PopularityBuilder_MakeNodes) -{ - TestPopularityBuilder::MakeNodes(); -} - -UNIT_CLASS_TEST(TestPopularityBuilder, PopularityBuilder_Build) -{ - TestPopularityBuilder::Build(); -} diff --git a/generator/generator_tool/generator_tool.cpp b/generator/generator_tool/generator_tool.cpp index 02cda90232..ba5e2e92ce 100644 --- a/generator/generator_tool/generator_tool.cpp +++ b/generator/generator_tool/generator_tool.cpp @@ -17,7 +17,6 @@ #include "generator/osm_source.hpp" #include "generator/platform_helpers.hpp" #include "generator/popular_places_section_builder.hpp" -#include "generator/popularity.hpp" #include "generator/processor_factory.hpp" #include "generator/ratings_section_builder.hpp" #include "generator/raw_generator.hpp" @@ -190,8 +189,6 @@ DEFINE_bool(generate_addresses_file, false, DEFINE_bool(generate_traffic_keys, false, "Generate keys for the traffic map (road segment -> speed group)."); -DEFINE_string(popularity_csv, "", "Output csv for popularity."); - DEFINE_bool(dump_mwm_tmp, false, "Prints feature builder objects from .mwm.tmp"); // Common. @@ -308,11 +305,6 @@ int GeneratorToolMain(int argc, char ** argv) if (FLAGS_make_routing_index || FLAGS_make_cross_mwm || FLAGS_make_transit_cross_mwm) countryParentGetter = make_unique(); - if (!FLAGS_popularity_csv.empty()) - { - popularity::BuildPopularitySrcFromAllData(genInfo.m_tmpDir, FLAGS_popularity_csv, threadsCount); - } - if (!FLAGS_dump_wikipedia_urls.empty()) { auto const tmpPath = base::JoinPath(genInfo.m_intermediateDir, "tmp"); diff --git a/generator/popularity.cpp b/generator/popularity.cpp deleted file mode 100644 index 3ee3651050..0000000000 --- a/generator/popularity.cpp +++ /dev/null @@ -1,326 +0,0 @@ -#include "generator/popularity.hpp" - -#include "generator/boost_helpers.hpp" -#include "generator/platform_helpers.hpp" - -#include "indexer/classificator.hpp" -#include "indexer/feature_utils.hpp" -#include "indexer/ftypes_matcher.hpp" - -#include "geometry/mercator.hpp" - -#include "base/assert.hpp" -#include "base/geo_object_id.hpp" -#include "base/thread_pool_computational.hpp" - -#include -#include -#include -#include -#include - -using namespace feature; - -namespace generator -{ -namespace popularity -{ -PopularityGeomPlace::PopularityGeomPlace(FeatureBuilder const & feature) - : m_id(feature.GetMostGenericOsmId()) - , m_feature(feature) - , m_polygon(std::make_unique()) -{ - CHECK(m_polygon, ()); - boost_helpers::FillPolygon(*m_polygon, m_feature); - m_area = boost::geometry::area(*m_polygon); -} - -bool PopularityGeomPlace::Contains(PopularityGeomPlace const & smaller) const -{ - CHECK(m_polygon, ()); - CHECK(smaller.m_polygon, ()); - - return GetFeature().GetLimitRect().IsRectInside(smaller.GetFeature().GetLimitRect()) && - boost::geometry::covered_by(*smaller.m_polygon, *m_polygon); -} - -bool PopularityGeomPlace::Contains(m2::PointD const & point) const -{ - CHECK(m_polygon, ()); - - return GetFeature().GetLimitRect().IsPointInside(point) && - boost::geometry::covered_by(BoostPoint(point.x, point.y), *m_polygon); -} - -PopularityBuilder::PopularityBuilder(std::string const & dataFilename) - : m_dataFilename(dataFilename) {} - -std::vector PopularityBuilder::Build() const -{ - std::vector pointObjs; - std::vector geomObjs; - auto const & checker = ftypes::IsPopularityPlaceChecker::Instance(); - ForEachFromDatRawFormat(m_dataFilename, [&](FeatureBuilder const & fb, uint64_t /* currPos */) { - if (!checker(fb.GetTypesHolder()) || GetFeatureName(fb).empty()) - return; - - if (fb.IsPoint()) - pointObjs.push_back(fb); - else if (fb.IsArea() && fb.IsGeometryClosed()) - geomObjs.push_back(fb); - }); - - auto geomObjsPtrs = MakeNodes(geomObjs); - auto const tree = MakeTree4d(geomObjsPtrs); - auto const mapIdToNode = GetAreaMap(geomObjsPtrs); - LinkGeomPlaces(mapIdToNode, tree, geomObjsPtrs); - - std::vector result; - FillLinesFromGeomObjectPtrs(geomObjsPtrs, result); - FillLinesFromPointObjects(pointObjs, mapIdToNode, tree, result); - return result; -} - -// static -std::string PopularityBuilder::GetType(FeatureBuilder const & feature) -{ - auto const & c = classif(); - auto const & checker = ftypes::IsPopularityPlaceChecker::Instance(); - auto const & types = feature.GetTypes(); - auto const it = std::find_if(std::begin(types), std::end(types), checker); - return it == std::end(types) ? string() : c.GetReadableObjectName(*it); -} - -// static -std::string PopularityBuilder::GetFeatureName(FeatureBuilder const & feature) -{ - auto const & str = feature.GetParams().name; - auto const deviceLang = StringUtf8Multilang::GetLangIndex("ru"); - std::string result; - GetReadableName({}, str, deviceLang, false /* allowTranslit */, result); - std::replace(std::begin(result), std::end(result), ';', ','); - std::replace(std::begin(result), std::end(result), '\n', ','); - return result; -} - -// static -void PopularityBuilder::FillLinesFromPointObjects(std::vector const & pointObjs, - MapIdToNode const & m, Tree4d const & tree, - std::vector & lines) -{ - lines.reserve(lines.size() + pointObjs.size()); - for (auto const & p : pointObjs) - { - auto const center = p.GetKeyPoint(); - PopularityLine line; - line.m_id = p.GetMostGenericOsmId(); - line.m_parent = FindPointParent(center, m, tree); - line.m_center = center; - line.m_type = GetType(p); - line.m_name = GetFeatureName(p); - lines.push_back(line); - } -} - -// static -boost::optional -PopularityBuilder::FindPointParent(m2::PointD const & point, MapIdToNode const & m, Tree4d const & tree) -{ - boost::optional bestId; - auto minArea = std::numeric_limits::max(); - tree.ForEachInRect({point, point}, [&](base::GeoObjectId const & id) { - if (m.count(id) == 0) - return; - - auto const & r = m.at(id)->GetData(); - if (r.GetArea() < minArea && r.Contains(point)) - { - minArea = r.GetArea(); - bestId = id; - } - }); - - return bestId; -} - -// static -boost::optional -PopularityBuilder::FindPopularityGeomPlaceParent(PopularityGeomPlace const & place, - MapIdToNode const & m, Tree4d const & tree) -{ - boost::optional bestPlace; - auto minArea = std::numeric_limits::max(); - auto const point = place.GetFeature().GetKeyPoint(); - tree.ForEachInRect({point, point}, [&](base::GeoObjectId const & id) { - if (m.count(id) == 0) - return; - - auto const & r = m.at(id)->GetData(); - if (r.GetId() == place.GetId() || r.GetArea() < place.GetArea()) - return; - - if (r.GetArea() < minArea && r.Contains(place)) - { - minArea = r.GetArea(); - bestPlace = m.at(id); - } - }); - - return bestPlace; -} - -// static -PopularityBuilder::MapIdToNode PopularityBuilder::GetAreaMap(Node::PtrList const & nodes) -{ - std::unordered_map result; - result.reserve(nodes.size()); - for (auto const & n : nodes) - { - auto const & d = n->GetData(); - result.emplace(d.GetId(), n); - } - - return result; -} - -// static -PopularityBuilder::Tree4d PopularityBuilder::MakeTree4d(Node::PtrList const & nodes) -{ - Tree4d tree; - for (auto const & n : nodes) - { - auto const & data = n->GetData(); - auto const & feature = data.GetFeature(); - tree.Add(data.GetId(), feature.GetLimitRect()); - } - - return tree; -} - -// static -void PopularityBuilder::FillLineFromGeomObjectPtr(PopularityLine & line, Node::Ptr const & node) -{ - auto const & data = node->GetData(); - auto const & feature = data.GetFeature(); - line.m_id = data.GetId(); - if (node->HasParent()) - line.m_parent = node->GetParent()->GetData().GetId(); - - line.m_center = feature.GetKeyPoint(); - line.m_type = GetType(feature); - line.m_name = GetFeatureName(feature); -} - -// static -void PopularityBuilder::FillLinesFromGeomObjectPtrs(Node::PtrList const & nodes, - std::vector & lines) -{ - lines.reserve(lines.size() + nodes.size()); - for (auto const & n : nodes) - { - PopularityLine line; - FillLineFromGeomObjectPtr(line, n); - lines.push_back(line); - } -} - -// static -void PopularityBuilder::LinkGeomPlaces(MapIdToNode const & m, Tree4d const & tree, Node::PtrList & nodes) -{ - if (nodes.size() < 2) - return; - - std::sort(std::begin(nodes), std::end(nodes), [](Node::Ptr const & l, Node::Ptr const & r) { - return l->GetData().GetArea() < r->GetData().GetArea(); - }); - - for (auto & node : nodes) - { - auto const & place = node->GetData(); - auto const parentPlace = FindPopularityGeomPlaceParent(place, m, tree); - if (!parentPlace) - continue; - - (*parentPlace)->AddChild(node); - node->SetParent(*parentPlace); - } -} - -// static -PopularityBuilder::Node::PtrList -PopularityBuilder::MakeNodes(std::vector const & features) -{ - Node::PtrList nodes; - nodes.reserve(features.size()); - std::transform(std::begin(features), std::end(features), std::back_inserter(nodes), [](FeatureBuilder const & f) { - return std::make_shared(PopularityGeomPlace(f)); - }); - - return nodes; -} - -std::vector BuildPopularitySrcFromData(std::string const & dataFilename) -{ - PopularityBuilder builder(dataFilename); - return builder.Build(); -} - -std::vector BuildPopularitySrcFromAllData(std::vector const & dataFilenames, - size_t cpuCount) -{ - CHECK_GREATER(cpuCount, 0, ()); - - base::thread_pool::computational::ThreadPool threadPool(cpuCount); - std::vector>> futures; - for (auto const & filename : dataFilenames) - { - auto result = threadPool.Submit( - static_cast(*)(std::string const &)>(BuildPopularitySrcFromData), - filename); - futures.emplace_back(std::move(result)); - } - - std::vector result; - for (auto & f : futures) - { - auto lines = f.get(); - std::move(std::begin(lines), std::end(lines), std::back_inserter(result)); - } - - return result; -} - -void WriteLines(std::vector const & lines, std::string const & outFilename) -{ - std::ofstream stream; - stream.exceptions(std::fstream::failbit | std::fstream::badbit); - stream.open(outFilename); - stream << std::fixed << std::setprecision(7); - stream << "Id;Parent id;Lat;Lon;Main type;Name\n"; - for (auto const & line : lines) - { - stream << line.m_id.GetEncodedId() << ";"; - if (line.m_parent) - stream << *line.m_parent; - - auto const center = MercatorBounds::ToLatLon(line.m_center); - stream << ";" << center.m_lat << ";" << center.m_lon << ";" - << line.m_type << ";" << line.m_name << "\n"; - } -} - -void BuildPopularitySrcFromData(std::string const & dataFilename, std::string const & outFilename) -{ - auto const lines = BuildPopularitySrcFromData(dataFilename); - WriteLines(lines, outFilename); -} - -void BuildPopularitySrcFromAllData(std::string const & dataDir, std::string const & outFilename, - size_t cpuCount) -{ - auto const filenames = platform_helpers::GetFullDataTmpFilePaths(dataDir); - auto const lines = BuildPopularitySrcFromAllData(filenames, cpuCount); - WriteLines(lines, outFilename); -} -} // namespace popularity -} // namespace generator diff --git a/generator/popularity.hpp b/generator/popularity.hpp deleted file mode 100644 index 33ecfbfa5e..0000000000 --- a/generator/popularity.hpp +++ /dev/null @@ -1,112 +0,0 @@ -#pragma once - -#include "generator/feature_builder.hpp" -#include "generator/place_node.hpp" - -#include "geometry/point2d.hpp" -#include "geometry/tree4d.hpp" - -#include "base/geo_object_id.hpp" - -#include -#include -#include -#include - -#include -#include - -namespace generator_tests -{ -class TestPopularityBuilder; -} // namespace generator_tests - -namespace generator -{ -namespace popularity -{ -// These are functions for generating a csv file for popularity. -// dataFilename - A path to data file -// dataDir - A path to the directory where the data files are located -// dataFilenames - Paths to data files -// cpuCount - A number of processes -// outFilename - A path where the csv file will be saved - -// Csv format: -// Id;Parent id;Lat;Lon;Main type;Name -// 9223372036936022489;;42.996411;41.004747;leisure-park;Сквер им. И. А. Когония -// 9223372037297546235;;43.325002;40.224941;leisure-park;Приморский парк -// 9223372036933918763;;43.005177;41.022295;leisure-park;Сухумский ботанический сад -void BuildPopularitySrcFromData(std::string const & dataFilename, std::string const & outFilename); - -void BuildPopularitySrcFromAllData(std::string const & dataDir, std::string const & outFilename, - size_t cpuCount = 1); - -void BuildPopularitySrcFromAllData(std::vector const & dataFilenames, std::string const & outFilename, - size_t cpuCount = 1); - -class PopularityGeomPlace -{ -public: - explicit PopularityGeomPlace(feature::FeatureBuilder const & feature); - - bool Contains(PopularityGeomPlace const & smaller) const; - bool Contains(m2::PointD const & point) const; - feature::FeatureBuilder const & GetFeature() const { return m_feature; } - double GetArea() const { return m_area; } - base::GeoObjectId GetId() const { return m_id; } - -private: - using BoostPoint = boost::geometry::model::point; - using BoostPolygon = boost::geometry::model::polygon; - - base::GeoObjectId m_id; - std::reference_wrapper m_feature; - std::unique_ptr m_polygon; - double m_area; -}; - -struct PopularityLine -{ - base::GeoObjectId m_id; - boost::optional m_parent; - m2::PointD m_center; - std::string m_type; - std::string m_name; -}; - -class PopularityBuilder -{ -public: - friend class generator_tests::TestPopularityBuilder; - - explicit PopularityBuilder(std::string const & dataFilename); - - std::vector Build() const; - -private: - using Node = PlaceNode; - using Tree4d = m4::Tree; - using MapIdToNode = std::unordered_map; - - static std::string GetType(feature::FeatureBuilder const & feature); - static std::string GetFeatureName(feature::FeatureBuilder const & feature); - static void FillLinesFromPointObjects(std::vector const & pointObjs, MapIdToNode const & m, - Tree4d const & tree, std::vector & lines); - static boost::optional - FindPointParent(m2::PointD const & point, MapIdToNode const & m, Tree4d const & tree); - static boost::optional - FindPopularityGeomPlaceParent(PopularityGeomPlace const & place, MapIdToNode const & m, - Tree4d const & tree); - static MapIdToNode GetAreaMap(Node::PtrList const & nodes); - static Tree4d MakeTree4d(Node::PtrList const & nodes); - static void FillLineFromGeomObjectPtr(PopularityLine & line, Node::Ptr const & node); - static void FillLinesFromGeomObjectPtrs(Node::PtrList const & nodes, - std::vector & lines); - static void LinkGeomPlaces(MapIdToNode const & m, Tree4d const & tree, Node::PtrList & nodes); - static Node::PtrList MakeNodes(std::vector const & features); - - std::string m_dataFilename; -}; -} // namespace popularity -} // namespace generator