From 866fb8a94d0601076732f36c72ddea23821b894d Mon Sep 17 00:00:00 2001 From: Anatoly Serdtcev Date: Thu, 10 Oct 2019 18:30:50 +0300 Subject: [PATCH] [generator] Refactor test support functions for line features --- generator/generator_tests/common.cpp | 62 ++++++++-- generator/generator_tests/common.hpp | 17 ++- .../generator_tests/geo_objects_tests.cpp | 6 +- generator/generator_tests/regions_tests.cpp | 116 ++++++++++-------- generator/key_value_storage.hpp | 1 - generator/streets/streets.cpp | 10 +- generator/streets/streets_builder.cpp | 39 +++--- generator/streets/streets_builder.hpp | 16 ++- 8 files changed, 178 insertions(+), 89 deletions(-) diff --git a/generator/generator_tests/common.cpp b/generator/generator_tests/common.cpp index da0793b..8938c3d 100644 --- a/generator/generator_tests/common.cpp +++ b/generator/generator_tests/common.cpp @@ -1,8 +1,10 @@ #include "generator/generator_tests/common.hpp" +#include "generator/feature_generator.hpp" #include "generator/osm2type.hpp" #include "indexer/classificator.hpp" +#include "indexer/classificator_loader.hpp" #include "platform/platform.hpp" @@ -36,8 +38,14 @@ OsmElement MakeOsmElement(OsmElementData const & elementData) { OsmElement el; el.m_id = elementData.m_id; - el.m_type = elementData.m_polygon.size() > 1 ? OsmElement::EntityType::Relation - : OsmElement::EntityType::Node; + + if (elementData.m_points.size() == 1) + el.m_type = OsmElement::EntityType::Node; + else if (elementData.m_points.front() == elementData.m_points.back()) + el.m_type = OsmElement::EntityType::Relation; + else + el.m_type = OsmElement::EntityType::Way; + for (auto const & tag : elementData.m_tags) el.AddTag(tag.m_key, tag.m_value); el.m_members = elementData.m_members; @@ -49,24 +57,42 @@ feature::FeatureBuilder FeatureBuilderFromOmsElementData(OsmElementData const & { auto el = MakeOsmElement(elementData); feature::FeatureBuilder fb; - CHECK(elementData.m_polygon.size() == 1 || elementData.m_polygon.size() == 2, ()); - if (elementData.m_polygon.size() == 1) + CHECK_GREATER_OR_EQUAL(elementData.m_points.size(), 1, ()); + if (elementData.m_points.size() == 1) { - fb.SetCenter(elementData.m_polygon[0]); + fb.SetCenter(elementData.m_points[0]); } - else if (elementData.m_polygon.size() == 2) + else if (elementData.m_points.front() == elementData.m_points.back()) { - auto const & p1 = elementData.m_polygon[0]; - auto const & p2 = elementData.m_polygon[1]; - std::vector poly = { - {p1.x, p1.y}, {p1.x, p2.y}, {p2.x, p2.y}, {p2.x, p1.y}, {p1.x, p1.y}}; + auto poly = elementData.m_points; fb.AddPolygon(poly); fb.SetHoles({}); fb.SetArea(); } + else + { + fb.SetLinear(); + for (auto const & point : elementData.m_points) + fb.AddPoint(point); + } - auto osmId = el.m_type == OsmElement::EntityType::Relation ? base::MakeOsmRelation(el.m_id) - : base::MakeOsmNode(el.m_id); + using base::GeoObjectId; + auto osmIdType = GeoObjectId::Type{}; + switch (el.m_type) + { + case OsmElement::EntityType::Node: + osmIdType = GeoObjectId::Type::ObsoleteOsmNode; + break; + case OsmElement::EntityType::Way: + osmIdType = GeoObjectId::Type::ObsoleteOsmWay; + break; + case OsmElement::EntityType::Relation: + osmIdType = GeoObjectId::Type::ObsoleteOsmRelation; + break; + default: + UNREACHABLE(); + } + auto osmId = GeoObjectId{osmIdType, el.m_id}; fb.SetOsmId(osmId); ftype::GetNameAndType(&el, fb.GetParams(), @@ -74,4 +100,16 @@ feature::FeatureBuilder FeatureBuilderFromOmsElementData(OsmElementData const & return fb; } +void WriteFeatures(std::vector const & osmElements, ScopedFile const & featuresFile) +{ + classificator::Load(); + + feature::FeaturesCollector collector(featuresFile.GetFullPath()); + for (auto const & elementData : osmElements) + { + auto fb = FeatureBuilderFromOmsElementData(elementData); + collector.Collect(fb); + } + collector.Finish(); +} } // namespace generator_tests diff --git a/generator/generator_tests/common.hpp b/generator/generator_tests/common.hpp index 699fa13..9793f29 100644 --- a/generator/generator_tests/common.hpp +++ b/generator/generator_tests/common.hpp @@ -3,6 +3,9 @@ #include "generator/osm_element.hpp" #include "geometry/point2d.hpp" +#include "geometry/rect2d.hpp" + +#include "platform/platform_tests_support/scoped_file.hpp" #include #include @@ -10,6 +13,7 @@ namespace generator_tests { using Tags = std::vector>; +using platform::tests_support::ScopedFile; OsmElement MakeOsmElement(uint64_t id, Tags const & tags, OsmElement::EntityType t); @@ -32,11 +36,22 @@ struct OsmElementData { uint64_t m_id; std::vector m_tags; - std::vector m_polygon; + std::vector m_points; std::vector m_members; }; // Use cautiously, nothing means it works with your osm types. OsmElement MakeOsmElement(OsmElementData const & elementData); feature::FeatureBuilder FeatureBuilderFromOmsElementData(OsmElementData const & elementData); + +struct RectArea : m2::RectD +{ + using m2::RectD::RectD; + + operator std::vector () const + { return {LeftBottom(), LeftTop(), RightTop(), RightBottom(), LeftBottom()}; } +}; + +void WriteFeatures(std::vector const & osmElements, + ScopedFile const & featuresFile); } // namespace generator_tests diff --git a/generator/generator_tests/geo_objects_tests.cpp b/generator/generator_tests/geo_objects_tests.cpp index 685a595..ff63009 100644 --- a/generator/generator_tests/geo_objects_tests.cpp +++ b/generator/generator_tests/geo_objects_tests.cpp @@ -178,7 +178,7 @@ UNIT_TEST(GenerateGeoObjects_AddNullBuildingGeometryForPointsWithAddressesInside {}}, {2, {{"building", "commercial"}, {"type", "multipolygon"}, {"name", "superbuilding"}}, - {{1, 1}, {4, 4}}, + RectArea{{1, 1}, {4, 4}}, {}}, {3, {{"addr:housenumber", "39 с80"}, {"addr:street", "Ленинградский проспект"}}, @@ -203,7 +203,7 @@ UNIT_TEST(GenerateGeoObjects_AddNullBuildingGeometryForPointsWithAddressesRevers {}}, {3, {{"building", "commercial"}, {"type", "multipolygon"}, {"name", "superbuilding"}}, - {{1, 1}, {4, 4}}, + RectArea{{1, 1}, {4, 4}}, {}}, }; @@ -262,7 +262,7 @@ UNIT_TEST(GenerateGeoObjects_CheckPoiEnrichedWithAddress) {1, {{"addr:housenumber", "111"}, {"addr:street", "Healing street"}}, {{1.6, 1.6}}, {}}, {2, {{"building", "commercial"}, {"type", "multipolygon"}, {"name", "superbuilding"}}, - {{1, 1}, {4, 4}}, + RectArea{{1, 1}, {4, 4}}, {}}, {3, {{"shop", "supermarket"}, {"population", "1"}, {"name", "ForgetMeNot"}}, diff --git a/generator/generator_tests/regions_tests.cpp b/generator/generator_tests/regions_tests.cpp index e46cd24..f32d01b 100644 --- a/generator/generator_tests/regions_tests.cpp +++ b/generator/generator_tests/regions_tests.cpp @@ -75,7 +75,7 @@ void BuildTestData(std::vector const & testData, RegionsBuilder: FeatureBuilder fb = FeatureBuilderFromOmsElementData(elementData); auto const id = fb.GetMostGenericOsmId(); - if (elementData.m_polygon.size() == 1) + if (elementData.m_points.size() == 1) placePointsMap.emplace(id, PlacePoint{fb, collector.Get(id)}); else regions.emplace_back(fb, collector.Get(id)); @@ -357,9 +357,10 @@ UNIT_TEST(RegionsBuilderTest_GenerateCityPointRegionByAround) auto regions = GenerateTestRegions( { - {1, {name = u8"Nederland", admin = "2", ba}, {{0.00, 0.00}, {0.50, 0.50}}, {}}, - {2, {name = u8"Nederland", admin = "3", ba}, {{0.10, 0.10}, {0.20, 0.20}}, {}}, - {3, {name = u8"Noord-Holland", admin = "4", ba}, {{0.12, 0.12}, {0.18, 0.18}}, {}}, + {1, {name = u8"Nederland", admin = "2", ba}, RectArea{{0.00, 0.00}, {0.50, 0.50}}, {}}, + {2, {name = u8"Nederland", admin = "3", ba}, RectArea{{0.10, 0.10}, {0.20, 0.20}}, {}}, + {3, {name = u8"Noord-Holland", admin = "4", ba}, RectArea{{0.12, 0.12}, {0.18, 0.18}}, + {}}, {6, {name = u8"Amsterdam", place = "city", admin = "2"}, {{0.15, 0.15}}, {}}, }, true /* withGeometry */); @@ -377,11 +378,12 @@ UNIT_TEST(RegionsBuilderTest_GenerateCityPointRegionByNameMatching) auto regions = GenerateTestRegions( { - {1, {name = u8"Nederland", admin = "2", ba}, {{0.00, 0.00}, {0.50, 0.50}}, {}}, - {2, {name = u8"Nederland", admin = "3", ba}, {{0.10, 0.10}, {0.20, 0.20}}, {}}, - {3, {name = u8"Noord-Holland", admin = "4", ba}, {{0.12, 0.12}, {0.18, 0.18}}, {}}, - {4, {name = u8"Amsterdam", admin = "8", ba}, {{0.14, 0.14}, {0.17, 0.17}}, {}}, - {5, {name = u8"Amsterdam", admin = "10", ba}, {{0.14, 0.14}, {0.16, 0.16}}, {}}, + {1, {name = u8"Nederland", admin = "2", ba}, RectArea{{0.00, 0.00}, {0.50, 0.50}}, {}}, + {2, {name = u8"Nederland", admin = "3", ba}, RectArea{{0.10, 0.10}, {0.20, 0.20}}, {}}, + {3, {name = u8"Noord-Holland", admin = "4", ba}, RectArea{{0.12, 0.12}, {0.18, 0.18}}, + {}}, + {4, {name = u8"Amsterdam", admin = "8", ba}, RectArea{{0.14, 0.14}, {0.17, 0.17}}, {}}, + {5, {name = u8"Amsterdam", admin = "10", ba}, RectArea{{0.14, 0.14}, {0.16, 0.16}}, {}}, {6, {name = u8"Amsterdam", place = "city", admin = "2"}, {{0.15, 0.15}}, {}}, }, true /* withGeometry */); @@ -400,13 +402,13 @@ UNIT_TEST(RegionsBuilderTest_GenerateCityPointRegionByEnglishNameMatching) { {1, {name = u8"België / Belgique / Belgien", admin = "2", ba}, - {{0.00, 0.00}, {0.50, 0.50}}, {}}, + RectArea{{0.00, 0.00}, {0.50, 0.50}}, {}}, {3, {name = u8"Ville de Bruxelles - Stad Brussel", admin = "8", ba}, - {{0.12, 0.12}, {0.18, 0.18}}, {}}, + RectArea{{0.12, 0.12}, {0.18, 0.18}}, {}}, {4, {name = u8"Bruxelles / Brussel", {"name:en", "Brussels"}, admin = "9", ba}, - {{0.12, 0.12}, {0.17, 0.17}}, {}}, + RectArea{{0.12, 0.12}, {0.17, 0.17}}, {}}, {5, {name = u8"Bruxelles - Brussel", {"name:en", "Brussels"}, place = "city"}, {{0.15, 0.15}}, {}}, @@ -428,9 +430,11 @@ UNIT_TEST(RegionsBuilderTest_GenerateCityPointRegionByNameMatchingWithCityPrefix auto regions = GenerateTestRegions( { - {1, {name = u8"United Kingdom", admin = "2", ba}, {{0.00, 0.00}, {0.50, 0.50}}, {}}, - {3, {name = u8"Scotland", admin = "4", ba}, {{0.12, 0.12}, {0.18, 0.18}}, {}}, - {4, {name = u8"City of Edinburgh", admin = "6", ba}, {{0.12, 0.12}, {0.17, 0.17}}, {}}, + {1, {name = u8"United Kingdom", admin = "2", ba}, RectArea{{0.00, 0.00}, {0.50, 0.50}}, + {}}, + {3, {name = u8"Scotland", admin = "4", ba}, RectArea{{0.12, 0.12}, {0.18, 0.18}}, {}}, + {4, {name = u8"City of Edinburgh", admin = "6", ba}, RectArea{{0.12, 0.12}, {0.17, 0.17}}, + {}}, {5, {name = u8"Edinburgh", place = "city"}, {{0.15, 0.15}}, {}}, }, true /* withGeometry */); @@ -450,9 +454,11 @@ UNIT_TEST(RegionsBuilderTest_GenerateCityPointRegionByNameMatchingWithCityPostfi auto regions = GenerateTestRegions( { - {1, {name = u8"United Kingdom", admin = "2", ba}, {{0.00, 0.00}, {0.50, 0.50}}, {}}, - {3, {name = u8"Scotland", admin = "4", ba}, {{0.12, 0.12}, {0.18, 0.18}}, {}}, - {4, {name = u8"Edinburgh (city)", admin = "6", ba}, {{0.12, 0.12}, {0.17, 0.17}}, {}}, + {1, {name = u8"United Kingdom", admin = "2", ba}, RectArea{{0.00, 0.00}, {0.50, 0.50}}, + {}}, + {3, {name = u8"Scotland", admin = "4", ba}, RectArea{{0.12, 0.12}, {0.18, 0.18}}, {}}, + {4, {name = u8"Edinburgh (city)", admin = "6", ba}, RectArea{{0.12, 0.12}, {0.17, 0.17}}, + {}}, {5, {name = u8"Edinburgh", place = "city"}, {{0.15, 0.15}}, {}}, }, true /* withGeometry */); @@ -472,9 +478,9 @@ UNIT_TEST(RegionsBuilderTest_GenerateCapitalPointRegionAndAdminRegionWithSameBou auto regions = GenerateTestRegions( { - {1, {name = u8"Country", admin = "2", ba}, {{0.00, 0.00}, {0.50, 0.50}}, {}}, - {2, {name = u8"Region", admin = "6", ba}, {{0.10, 0.10}, {0.20, 0.20}}, {}}, - {3, {name = u8"Washington", admin = "8", ba}, {{0.10, 0.10}, {0.20, 0.20}}, {}}, + {1, {name = u8"Country", admin = "2", ba}, RectArea{{0.00, 0.00}, {0.50, 0.50}}, {}}, + {2, {name = u8"Region", admin = "6", ba}, RectArea{{0.10, 0.10}, {0.20, 0.20}}, {}}, + {3, {name = u8"Washington", admin = "8", ba}, RectArea{{0.10, 0.10}, {0.20, 0.20}}, {}}, {4, {name = u8"Washington", place = "city", admin = "2"}, {{0.15, 0.15}}, {}}, }, true /* withGeometry */); @@ -493,16 +499,18 @@ UNIT_TEST(RegionsBuilderTest_GenerateRusCitySuburb) TagValue const ba{"boundary", "administrative"}; auto regions = GenerateTestRegions({ - {1, {name = u8"Россия", admin = "2", ba}, {{0, 0}, {50, 50}}, {}}, - {2, {name = u8"Сибирский федеральный округ", admin = "3", ba}, {{10, 10}, {20, 20}}, {}}, - {3, {name = u8"Омская область", admin = "4", ba}, {{12, 12}, {18, 18}}, {}}, - {4, {name = u8"Омск", place = "city"}, {{14, 14}, {16, 16}}, {}}, + {1, {name = u8"Россия", admin = "2", ba}, RectArea{{0, 0}, {50, 50}}, {}}, + {2, {name = u8"Сибирский федеральный округ", admin = "3", ba}, RectArea{{10, 10}, {20, 20}}, + {}}, + {3, {name = u8"Омская область", admin = "4", ba}, RectArea{{12, 12}, {18, 18}}, {}}, + {4, {name = u8"Омск", place = "city"}, RectArea{{14, 14}, {16, 16}}, {}}, {5, {name = u8"городской округ Омск", admin = "6", ba}, - {{14, 14}, {16, 16}}, + RectArea{{14, 14}, {16, 16}}, {{6, NodeEntry, "admin_centre"}}}, {6, {name = u8"Омск", place = "city"}, {{15, 15}}, {}}, - {7, {name = u8"Кировский административный округ", admin = "9", ba}, {{14, 14}, {15, 15}}, {}}, + {7, {name = u8"Кировский административный округ", admin = "9", ba}, + RectArea{{14, 14}, {15, 15}}, {}}, }); TEST(HasName(regions, @@ -523,17 +531,22 @@ UNIT_TEST(RegionsBuilderTest_GenerateRusMoscowSubregion) TagValue const ba{"boundary", "administrative"}; auto regions = GenerateTestRegions({ - {1, {name = u8"Россия", admin = "2", ba}, {{0, 0}, {50, 50}}, {}}, - {2, {name = u8"Центральный федеральный округ", admin = "3", ba}, {{10, 10}, {20, 20}}, {}}, - {3, {name = u8"Москва", admin = "4", ba}, {{12, 12}, {16, 16}}, {}}, + {1, {name = u8"Россия", admin = "2", ba}, RectArea{{0, 0}, {50, 50}}, {}}, + {2, {name = u8"Центральный федеральный округ", admin = "3", ba}, RectArea{{10, 10}, {20, 20}}, + {}}, + {3, {name = u8"Москва", admin = "4", ba}, RectArea{{12, 12}, {16, 16}}, {}}, - {4, {name = u8"Западный административный округ", admin = "5", ba}, {{12, 12}, {13, 13}}, {}}, - {4, {name = u8"Западный административный округ", admin = "5", ba}, {{13, 13}, {15, 14}}, {}}, - {5, {name = u8"Северный административный округ", admin = "5", ba}, {{13, 14}, {15, 15}}, {}}, - {6, {name = u8"Троицкий административный округ", admin = "5", ba}, {{15, 15}, {16, 16}}, {}}, + {4, {name = u8"Западный административный округ", admin = "5", ba}, + RectArea{{12, 12}, {13, 13}}, {}}, + {4, {name = u8"Западный административный округ", admin = "5", ba}, + RectArea{{13, 13}, {15, 14}}, {}}, + {5, {name = u8"Северный административный округ", admin = "5", ba}, + RectArea{{13, 14}, {15, 15}}, {}}, + {6, {name = u8"Троицкий административный округ", admin = "5", ba}, + RectArea{{15, 15}, {16, 16}}, {}}, - {7, {name = u8"Москва", place = "city"}, {{12, 12}, {13, 13}}, {}}, - {7, {name = u8"Москва", place = "city"}, {{13, 13}, {15, 15}}, {}}, + {7, {name = u8"Москва", place = "city"}, RectArea{{12, 12}, {13, 13}}, {}}, + {7, {name = u8"Москва", place = "city"}, RectArea{{13, 13}, {15, 15}}, {}}, }); TEST(HasName(regions, u8"Россия, region: Москва"), ()); @@ -562,19 +575,21 @@ UNIT_TEST(RegionsBuilderTest_GenerateRusMoscowSuburb) TagValue const ba{"boundary", "administrative"}; auto regions = GenerateTestRegions({ - {1, {name = u8"Россия", admin = "2", ba}, {{0, 0}, {50, 50}}, {}}, - {2, {name = u8"Центральный федеральный округ", admin = "3", ba}, {{10, 10}, {20, 20}}, {}}, - {3, {name = u8"Москва", admin = "4", ba}, {{12, 12}, {20, 20}}, {}}, - {4, {name = u8"Москва", place = "city"}, {{12, 12}, {19, 19}}, {}}, - {5, {name = u8"Западный административный округ", admin = "5", ba}, {{12, 12}, {18, 18}}, {}}, + {1, {name = u8"Россия", admin = "2", ba}, RectArea{{0, 0}, {50, 50}}, {}}, + {2, {name = u8"Центральный федеральный округ", admin = "3", ba}, + RectArea{{10, 10}, {20, 20}}, {}}, + {3, {name = u8"Москва", admin = "4", ba}, RectArea{{12, 12}, {20, 20}}, {}}, + {4, {name = u8"Москва", place = "city"}, RectArea{{12, 12}, {19, 19}}, {}}, + {5, {name = u8"Западный административный округ", admin = "5", ba}, + RectArea{{12, 12}, {18, 18}}, {}}, {6, {name = u8"район Раменки", admin = "8", ba}, - {{12, 12}, {15, 15}}, + RectArea{{12, 12}, {15, 15}}, {{7, NodeEntry, "label"}}}, {7, {name = u8"Раменки", place = "suburb"}, {{13, 13}}, {}}, // label {8, {name = u8"Тропарёво", place = "suburb"}, {{16, 16}}, {}}, // no label - {9, {name = u8"Воробъёвы горы", place = "suburb"}, {{12, 12}, {14, 14}}, {}}, - {10, {name = u8"Центр", place = "suburb"}, {{15, 15}, {16, 16}}, {}}, + {9, {name = u8"Воробъёвы горы", place = "suburb"}, RectArea{{12, 12}, {14, 14}}, {}}, + {10, {name = u8"Центр", place = "suburb"}, RectArea{{15, 15}, {16, 16}}, {}}, }); TEST(HasName(regions, u8"Россия, region: Москва"), ()); @@ -606,12 +621,13 @@ UNIT_TEST(RegionsBuilderTest_GenerateRusSPetersburgSuburb) TagValue const ba{"boundary", "administrative"}; auto regions = GenerateTestRegions({ - {1, {name = u8"Россия", admin = "2", ba}, {{0, 0}, {50, 50}}, {}}, - {2, {name = u8"Северо-Западный федеральный округ", admin = "3", ba}, {{10, 10}, {20, 20}}, {}}, - {3, {name = u8"Санкт-Петербург", admin = "4", ba}, {{12, 12}, {18, 18}}, {}}, - {4, {name = u8"Санкт-Петербург", place = "city"}, {{12, 12}, {17, 17}}, {}}, - {5, {name = u8"Центральный район", admin = "5", ba}, {{14, 14}, {16, 16}}, {}}, - {6, {name = u8"Дворцовый округ", admin = "8", ba}, {{14, 14}, {15, 15}} , {}}, + {1, {name = u8"Россия", admin = "2", ba}, RectArea{{0, 0}, {50, 50}}, {}}, + {2, {name = u8"Северо-Западный федеральный округ", admin = "3", ba}, + RectArea{{10, 10}, {20, 20}}, {}}, + {3, {name = u8"Санкт-Петербург", admin = "4", ba}, RectArea{{12, 12}, {18, 18}}, {}}, + {4, {name = u8"Санкт-Петербург", place = "city"}, RectArea{{12, 12}, {17, 17}}, {}}, + {5, {name = u8"Центральный район", admin = "5", ba}, RectArea{{14, 14}, {16, 16}}, {}}, + {6, {name = u8"Дворцовый округ", admin = "8", ba}, RectArea{{14, 14}, {15, 15}} , {}}, }); TEST(HasName(regions, u8"Россия, region: Санкт-Петербург, locality: Санкт-Петербург"), ()); diff --git a/generator/key_value_storage.hpp b/generator/key_value_storage.hpp index a489fd1..f7f41a8 100644 --- a/generator/key_value_storage.hpp +++ b/generator/key_value_storage.hpp @@ -8,7 +8,6 @@ #include #include -#include #include #include "3party/jansson/myjansson.hpp" diff --git a/generator/streets/streets.cpp b/generator/streets/streets.cpp index a833597..6d31d9c 100644 --- a/generator/streets/streets.cpp +++ b/generator/streets/streets.cpp @@ -28,7 +28,10 @@ void GenerateStreets(std::string const & pathInRegionsIndex, std::string const & regions::RegionInfoGetter regionInfoGetter{pathInRegionsIndex, pathInRegionsKv}; LOG(LINFO, ("Size of regions key-value storage:", regionInfoGetter.GetStorage().Size())); - StreetsBuilder streetsBuilder{regionInfoGetter, threadsCount}; + auto const regionFinder = [®ionInfoGetter] (auto && point, auto && selector) { + return regionInfoGetter.FindDeepest(point, selector); + }; + StreetsBuilder streetsBuilder{regionFinder, threadsCount}; streetsBuilder.AssembleStreets(pathInStreetsTmpMwm); LOG(LINFO, ("Streets were built.")); @@ -40,7 +43,10 @@ void GenerateStreets(std::string const & pathInRegionsIndex, std::string const & LOG(LINFO, ("Streets features are aggreated into", pathInStreetsTmpMwm)); std::ofstream streamStreetsKv(pathOutStreetsKv); - streetsBuilder.SaveStreetsKv(streamStreetsKv); + auto const regionGetter = [®ionStorage = regionInfoGetter.GetStorage()](uint64_t id) { + return regionStorage.Find(id); + }; + streetsBuilder.SaveStreetsKv(regionGetter, streamStreetsKv); LOG(LINFO, ("Streets key-value storage saved to", pathOutStreetsKv)); } } // namespace streets diff --git a/generator/streets/streets_builder.cpp b/generator/streets/streets_builder.cpp index 77102fd..d291104 100644 --- a/generator/streets/streets_builder.cpp +++ b/generator/streets/streets_builder.cpp @@ -26,16 +26,19 @@ namespace generator { namespace streets { -StreetsBuilder::StreetsBuilder(regions::RegionInfoGetter const & regionInfoGetter, +StreetsBuilder::StreetsBuilder(RegionFinder const & regionFinder, size_t threadsCount) - : m_regionInfoGetter{regionInfoGetter}, m_threadsCount{threadsCount} + : m_regionFinder{regionFinder}, m_threadsCount{threadsCount} { } void StreetsBuilder::AssembleStreets(std::string const & pathInStreetsTmpMwm) { auto const transform = [this](FeatureBuilder & fb, uint64_t /* currPos */) { AddStreet(fb); }; - ForEachParallelFromDatRawFormat(m_threadsCount, pathInStreetsTmpMwm, transform); + if (m_threadsCount == 1) + ForEachFromDatRawFormat(pathInStreetsTmpMwm, transform); + else + ForEachParallelFromDatRawFormat(m_threadsCount, pathInStreetsTmpMwm, transform); } void StreetsBuilder::AssembleBindings(std::string const & pathInGeoObjectsTmpMwm) @@ -50,7 +53,11 @@ void StreetsBuilder::AssembleBindings(std::string const & pathInGeoObjectsTmpMwm AddStreetBinding(std::move(streetName), fb, multilangName); } }; - ForEachParallelFromDatRawFormat(m_threadsCount, pathInGeoObjectsTmpMwm, transform); + + if (m_threadsCount == 1) + ForEachFromDatRawFormat(pathInGeoObjectsTmpMwm, transform); + else + ForEachParallelFromDatRawFormat(m_threadsCount, pathInGeoObjectsTmpMwm, transform); } void StreetsBuilder::RegenerateAggreatedStreetsFeatures( @@ -74,6 +81,8 @@ void StreetsBuilder::RegenerateAggreatedStreetsFeatures( }; ForEachFromDatRawFormat(pathStreetsTmpMwm, transform); + collector.Finish(); + CHECK(base::RenameFileX(aggregatedStreetsTmpFile, pathStreetsTmpMwm), ()); } @@ -119,19 +128,21 @@ void StreetsBuilder::WriteAsAggregatedStreet(FeatureBuilder & fb, Street const & } } -void StreetsBuilder::SaveStreetsKv(std::ostream & streamStreetsKv) +void StreetsBuilder::SaveStreetsKv(RegionGetter const & regionGetter, + std::ostream & streamStreetsKv) { for (auto const & region : m_regions) - SaveRegionStreetsKv(streamStreetsKv, region.first, region.second); + { + auto const && regionObject = regionGetter(region.first); + CHECK(regionObject, ()); + SaveRegionStreetsKv(region.second, region.first, *regionObject, streamStreetsKv); + } } -void StreetsBuilder::SaveRegionStreetsKv(std::ostream & streamStreetsKv, uint64_t regionId, - RegionStreets const & streets) +void StreetsBuilder::SaveRegionStreetsKv(RegionStreets const & streets, uint64_t regionId, + JsonValue const & regionInfo, + std::ostream & streamStreetsKv) { - auto const & regionsStorage = m_regionInfoGetter.GetStorage(); - auto const && regionObject = regionsStorage.Find(regionId); - ASSERT(regionObject, ()); - for (auto const & street : streets) { auto const & bbox = street.second.m_geometry.GetBbox(); @@ -139,7 +150,7 @@ void StreetsBuilder::SaveRegionStreetsKv(std::ostream & streamStreetsKv, uint64_ auto const id = KeyValueStorage::SerializeDref(pin.m_osmId.GetEncodedId()); auto const & value = - MakeStreetValue(regionId, *regionObject, street.second.m_name, bbox, pin.m_position); + MakeStreetValue(regionId, regionInfo, street.second.m_name, bbox, pin.m_position); streamStreetsKv << id << " " << KeyValueStorage::Serialize(value) << "\n"; } } @@ -238,7 +249,7 @@ boost::optional StreetsBuilder::FindStreetRegionOwner(m2::PointD const return true; }; - return m_regionInfoGetter.FindDeepest(point, isStreetAdministrator); + return m_regionFinder(point, isStreetAdministrator); } StringUtf8Multilang MergeNames(const StringUtf8Multilang & first, diff --git a/generator/streets/streets_builder.hpp b/generator/streets/streets_builder.hpp index 7e7ae5e..8edd0f7 100644 --- a/generator/streets/streets_builder.hpp +++ b/generator/streets/streets_builder.hpp @@ -2,7 +2,6 @@ #include "generator/feature_builder.hpp" #include "generator/feature_generator.hpp" -#include "generator/key_value_storage.hpp" #include "generator/osm_element.hpp" #include "generator/regions/region_info_getter.hpp" #include "generator/streets/street_geometry.hpp" @@ -13,6 +12,7 @@ #include "base/geo_object_id.hpp" +#include #include #include #include @@ -29,7 +29,11 @@ namespace streets class StreetsBuilder { public: - explicit StreetsBuilder(regions::RegionInfoGetter const & regionInfoGetter, size_t threadsCount); + using RegionFinder = std::function( + m2::PointD const & point, std::function const & selector)>; + using RegionGetter = std::function(uint64_t key)>; + + explicit StreetsBuilder(RegionFinder const & regionFinder, size_t threadsCount = 1); void AssembleStreets(std::string const & pathInStreetsTmpMwm); void AssembleBindings(std::string const & pathInGeoObjectsTmpMwm); @@ -39,7 +43,7 @@ public: // Save built streets in the jsonl format with the members: "properties", "bbox" (array: left // bottom longitude, left bottom latitude, right top longitude, right top latitude), "pin" (array: // longitude, latitude). - void SaveStreetsKv(std::ostream & streamStreetsKv); + void SaveStreetsKv(RegionGetter const & regionGetter, std::ostream & streamStreetsKv); static bool IsStreet(OsmElement const & element); static bool IsStreet(feature::FeatureBuilder const & fb); @@ -55,8 +59,8 @@ private: void WriteAsAggregatedStreet(feature::FeatureBuilder & fb, Street const & street, feature::FeaturesCollector & collector) const; - void SaveRegionStreetsKv(std::ostream & streamStreetsKv, uint64_t regionId, - RegionStreets const & streets); + void SaveRegionStreetsKv(RegionStreets const & streets, uint64_t regionId, + JsonValue const & regionInfo, std::ostream & streamStreetsKv); void AddStreet(feature::FeatureBuilder & fb); void AddStreetHighway(feature::FeatureBuilder & fb); @@ -75,7 +79,7 @@ private: std::unordered_map m_regions; std::unordered_multimap m_streetFeatures2Streets; - regions::RegionInfoGetter const & m_regionInfoGetter; + RegionFinder m_regionFinder; uint64_t m_osmSurrogateCounter{0}; size_t m_threadsCount; std::mutex m_updateMutex;