From d6b82b98e4b7e6b12963d9caa6aaeeda73f4a7c8 Mon Sep 17 00:00:00 2001 From: Viktor Govako Date: Wed, 6 Apr 2022 14:23:46 +0300 Subject: [PATCH] [generator] FeatureBuilder geometry refactoring. Signed-off-by: Viktor Govako --- generator/coastlines_generator.cpp | 21 ++- generator/feature_builder.cpp | 121 +++++------------- generator/feature_builder.hpp | 21 +-- generator/feature_maker.cpp | 29 +++-- generator/feature_merger.hpp | 2 +- generator/feature_sorter.cpp | 3 + .../generator_tests/affiliation_tests.cpp | 5 +- .../generator_tests/cities_ids_tests.cpp | 27 ---- .../collector_city_area_tests.cpp | 3 +- ...ollector_routing_city_boundaries_tests.cpp | 11 +- .../cross_mwm_osm_ways_collector_tests.cpp | 11 +- .../generator_tests/feature_builder_test.cpp | 11 +- .../generator_tests/feature_merger_test.cpp | 48 ++----- generator/generator_tests/hierarchy_tests.cpp | 15 +-- .../generator_tests/place_processor_tests.cpp | 7 +- .../generator_tests_support/test_feature.cpp | 103 +++++++-------- .../generator_tests_support/test_feature.hpp | 24 ++-- generator/isolines_generator.cpp | 9 +- generator/mini_roundabout_transformer.cpp | 34 ++--- generator/water_boundary_checker.hpp | 24 ++-- generator/ways_merger.hpp | 2 +- 21 files changed, 196 insertions(+), 335 deletions(-) diff --git a/generator/coastlines_generator.cpp b/generator/coastlines_generator.cpp index c4f2838bb2..1333dddecc 100644 --- a/generator/coastlines_generator.cpp +++ b/generator/coastlines_generator.cpp @@ -83,7 +83,6 @@ class DoDifference { RectT m_src; std::vector m_res; - std::vector m_points; public: explicit DoDifference(RegionT const & rgn) @@ -102,12 +101,6 @@ public: m2::IntersectRegions(m_res.front(), r, m_res); } - void operator()(PointT const & p) - { - m_points.push_back(PointUToPointD( - m2::PointU(static_cast(p.x), static_cast(p.y)), kPointCoordBits)); - } - size_t GetPointsCount() const { size_t count = 0; @@ -120,10 +113,16 @@ public: { for (size_t i = 0; i < m_res.size(); ++i) { - m_points.clear(); - m_points.reserve(m_res[i].Size() + 1); - m_res[i].ForEachPoint(std::ref(*this)); - fb.AddPolygon(m_points); + std::vector points; + points.reserve(m_res[i].Size() + 1); + + m_res[i].ForEachPoint([&points](PointT const & p) + { + points.push_back(PointUToPointD( + m2::PointU(static_cast(p.x), static_cast(p.y)), kPointCoordBits)); + }); + + fb.AddPolygon(std::move(points)); } } }; diff --git a/generator/feature_builder.cpp b/generator/feature_builder.cpp index 02b01fefa1..42c61e9a85 100644 --- a/generator/feature_builder.cpp +++ b/generator/feature_builder.cpp @@ -23,6 +23,8 @@ #include #include +namespace feature +{ namespace { bool IsEqual(double d1, double d2) @@ -66,12 +68,9 @@ void ReadPOD(Sink & src, T & value) } } // namespace -namespace feature -{ FeatureBuilder::FeatureBuilder() : m_coastCell(-1) { - m_polygons.push_back(PointSeq()); } bool FeatureBuilder::IsGeometryClosed() const @@ -119,16 +118,18 @@ void FeatureBuilder::SetRank(uint8_t rank) m_params.rank = rank; } -void FeatureBuilder::AddPoint(m2::PointD const & p) +void FeatureBuilder::AssignPoints(PointSeq points) { - m_polygons.front().push_back(p); - m_limitRect.Add(p); + ResetGeometry(); + + CalcRect(points, m_limitRect); + + m_polygons.emplace_back(std::move(points)); } void FeatureBuilder::SetLinear(bool reverseGeometry) { m_params.SetGeomType(GeomType::Line); - m_polygons.resize(1); if (reverseGeometry) { @@ -138,11 +139,12 @@ void FeatureBuilder::SetLinear(bool reverseGeometry) } } -void FeatureBuilder::SetHoles(FeatureBuilder::Geometry const & holes) +void FeatureBuilder::AssignArea(PointSeq && outline, Geometry const & holes) { - m_polygons.resize(1); + AssignPoints(std::move(outline)); - if (holes.empty()) return; + if (holes.empty()) + return; PointSeq const & poly = GetOuterGeometry(); m2::Region rgn(poly.begin(), poly.end()); @@ -162,7 +164,7 @@ void FeatureBuilder::SetHoles(FeatureBuilder::Geometry const & holes) } } -void FeatureBuilder::AddPolygon(std::vector & poly) +void FeatureBuilder::AddPolygon(PointSeq && poly) { // check for closing if (poly.size() < 3) @@ -173,16 +175,12 @@ void FeatureBuilder::AddPolygon(std::vector & poly) CalcRect(poly, m_limitRect); - if (!m_polygons.back().empty()) - m_polygons.push_back(PointSeq()); - - m_polygons.back().swap(poly); + m_polygons.push_back(std::move(poly)); } void FeatureBuilder::ResetGeometry() { m_polygons.clear(); - m_polygons.push_back(PointSeq()); m_limitRect.MakeEmpty(); } @@ -313,7 +311,7 @@ void FeatureBuilder::RemoveUselessNames() m_params.name.Clear(); } - // We want to skip alt_name which is almost equal to name. + // Skip the alt_name which is equal to the default name. std::string_view name, altName; if (m_params.name.GetString(StringUtf8Multilang::kAltNameCode, altName) && m_params.name.GetString(StringUtf8Multilang::kDefaultCode, name) && @@ -409,32 +407,6 @@ void FeatureBuilder::SerializeForIntermediate(Buffer & data) const #endif } -void FeatureBuilder::SerializeBorderForIntermediate(serial::GeometryCodingParams const & params, - Buffer & data) const -{ - data.clear(); - - PushBackByteSink sink(data); - WriteToSink(sink, GetMostGenericOsmId().GetEncodedId()); - - CHECK_GREATER(m_polygons.size(), 0, ()); - - WriteToSink(sink, m_polygons.size() - 1); - - auto toU = [¶ms](m2::PointD const & p) { return PointDToPointU(p, params.GetCoordBits()); }; - for (auto const & polygon : m_polygons) - { - WriteToSink(sink, polygon.size()); - m2::PointU last = params.GetBasePoint(); - for (auto const & p : polygon) - { - auto const curr = toU(p); - coding::EncodePointDelta(sink, last, curr); - last = curr; - } - } -} - void FeatureBuilder::DeserializeFromIntermediate(Buffer & data) { serial::GeometryCodingParams cp; @@ -572,14 +544,9 @@ base::GeoObjectId FeatureBuilder::GetMostGenericOsmId() const return result; } -bool FeatureBuilder::HasOsmId(base::GeoObjectId const & id) const +std::string FeatureBuilder::DebugPrintIDs() const { - for (auto const & cid : m_osmIds) - { - if (cid == id) - return true; - } - return false; + return ::DebugPrint(m_osmIds); } bool FeatureBuilder::AddName(std::string_view lang, std::string_view name) @@ -604,16 +571,12 @@ size_t FeatureBuilder::GetPointsCount() const bool FeatureBuilder::IsDrawableInRange(int lowScale, int highScale) const { - if (!GetOuterGeometry().empty()) + auto const types = GetTypesHolder(); + while (lowScale <= highScale) { - auto const types = GetTypesHolder(); - while (lowScale <= highScale) - { - if (IsDrawableForIndex(types, m_limitRect, lowScale++)) - return true; - } + if (IsDrawableForIndex(types, m_limitRect, lowScale++)) + return true; } - return false; } @@ -649,33 +612,6 @@ bool FeatureBuilder::PreSerializeAndRemoveUselessNamesForMwm(SupportingData cons return true; } -void FeatureBuilder::SerializeLocalityObject(serial::GeometryCodingParams const & params, - SupportingData & data) const -{ - data.m_buffer.clear(); - - PushBackByteSink sink(data.m_buffer); - WriteToSink(sink, GetMostGenericOsmId().GetEncodedId()); - - auto const type = m_params.GetGeomType(); - WriteToSink(sink, static_cast(type)); - - if (type == GeomType::Point) - { - serial::SavePoint(sink, m_center, params); - return; - } - - CHECK_EQUAL(type, GeomType::Area, ("Supported types are Point and Area")); - - uint32_t trgCount = base::asserted_cast(data.m_innerTrg.size()); - CHECK_GREATER(trgCount, 2, ()); - trgCount -= 2; - - WriteToSink(sink, trgCount); - serial::SaveInnerTriangles(data.m_innerTrg, params, sink); -} - void FeatureBuilder::SerializeForMwm(SupportingData & data, serial::GeometryCodingParams const & params) const { @@ -736,10 +672,11 @@ void FeatureBuilder::SerializeForMwm(SupportingData & data, } else { - ASSERT_GREATER ( GetOuterGeometry().size(), 2, () ); + auto const & poly = GetOuterGeometry(); + ASSERT_GREATER(poly.size(), 2, ()); // Store first point once for outer linear features. - serial::SavePoint(sink, GetOuterGeometry()[0], params); + serial::SavePoint(sink, poly[0], params); // offsets was pushed from high scale index to low reverse(data.m_ptsOffset.begin(), data.m_ptsOffset.end()); @@ -764,12 +701,16 @@ bool FeatureBuilder::IsValid() const if (!GetParams().IsValid()) return false; - if (IsLine() && GetOuterGeometry().size() < 2) + auto const & geom = GetGeometry(); + if (IsLine() && (geom.empty() || GetOuterGeometry().size() < 2)) return false; if (IsArea()) { - for (auto const & points : GetGeometry()) + if (geom.empty()) + return false; + + for (auto const & points : geom) { if (points.size() < 3) return false; @@ -793,7 +734,7 @@ std::string DebugPrint(FeatureBuilder const & fb) out << " " << DebugPrint(mercator::ToLatLon(fb.GetLimitRect())) << " " << DebugPrint(fb.GetParams()) - << " " << ::DebugPrint(fb.m_osmIds); + << " " << fb.DebugPrintIDs(); return out.str(); } diff --git a/generator/feature_builder.hpp b/generator/feature_builder.hpp index 87c5151a12..3eb0771d17 100644 --- a/generator/feature_builder.hpp +++ b/generator/feature_builder.hpp @@ -56,13 +56,18 @@ public: /// @name To work with geometry. ///@{ - void AddPoint(m2::PointD const & p); - void SetHoles(Geometry const & holes); - void AddPolygon(std::vector & poly); + void AssignPoints(PointSeq points); + void AssignArea(PointSeq && outline, Geometry const & holes); + void AddPolygon(PointSeq && poly); void ResetGeometry(); + m2::RectD const & GetLimitRect() const { return m_limitRect; } Geometry const & GetGeometry() const { return m_polygons; } - PointSeq const & GetOuterGeometry() const { return m_polygons.front(); } + PointSeq const & GetOuterGeometry() const + { + CHECK(!m_polygons.empty(), ()); + return m_polygons.front(); + } GeomType GetGeomType() const { return m_params.GetGeomType(); } bool IsGeometryClosed() const; m2::PointD GetGeometryCenter() const; @@ -133,7 +138,6 @@ public: bool HasType(uint32_t t) const { return m_params.IsTypeExist(t); } bool HasType(uint32_t t, uint8_t level) const { return m_params.IsTypeExist(t, level); } - uint32_t FindType(uint32_t comp, uint8_t level) const { return m_params.FindType(comp, level); } FeatureParams::Types const & GetTypes() const { return m_params.m_types; } size_t GetTypesCount() const { return m_params.m_types.size(); } ///@} @@ -170,9 +174,8 @@ public: ///@{ bool PreSerialize(); bool PreSerializeAndRemoveUselessNamesForIntermediate(); + void SerializeForIntermediate(Buffer & data) const; - void SerializeBorderForIntermediate(serial::GeometryCodingParams const & params, - Buffer & data) const; void DeserializeFromIntermediate(Buffer & data); // These methods use geometry without loss of accuracy. @@ -180,8 +183,6 @@ public: void DeserializeAccuratelyFromIntermediate(Buffer & data); bool PreSerializeAndRemoveUselessNamesForMwm(SupportingData const & data); - void SerializeLocalityObject(serial::GeometryCodingParams const & params, - SupportingData & data) const; void SerializeForMwm(SupportingData & data, serial::GeometryCodingParams const & params) const; ///@} @@ -197,8 +198,8 @@ public: // Returns an id of the most general element: node's one if there is no area or relation, // area's one if there is no relation, and relation id otherwise. base::GeoObjectId GetMostGenericOsmId() const; - bool HasOsmId(base::GeoObjectId const & id) const; bool HasOsmIds() const { return !m_osmIds.empty(); } + std::string DebugPrintIDs() const; ///@} // To work with coasts. diff --git a/generator/feature_maker.cpp b/generator/feature_maker.cpp index 4f0dd04723..941121f68c 100644 --- a/generator/feature_maker.cpp +++ b/generator/feature_maker.cpp @@ -79,8 +79,10 @@ bool FeatureMakerSimple::BuildFromNode(OsmElement & p, FeatureBuilderParams cons { FeatureBuilder fb; fb.SetCenter(mercator::FromLatLon(p.m_lat, p.m_lon)); + fb.SetOsmId(base::MakeOsmNode(p.m_id)); fb.SetParams(params); + m_queue.push(std::move(fb)); return true; } @@ -92,17 +94,21 @@ bool FeatureMakerSimple::BuildFromWay(OsmElement & p, FeatureBuilderParams const return false; FeatureBuilder fb; - m2::PointD pt; + + std::vector points; + points.reserve(nodes.size()); for (uint64_t ref : nodes) { + m2::PointD pt; if (!m_cache->GetNode(ref, pt.y, pt.x)) return false; - - fb.AddPoint(pt); + points.push_back(pt); } + fb.AssignPoints(std::move(points)); fb.SetOsmId(base::MakeOsmWay(p.m_id)); fb.SetParams(params); + if (fb.IsGeometryClosed()) fb.SetArea(); else @@ -117,28 +123,25 @@ bool FeatureMakerSimple::BuildFromRelation(OsmElement & p, FeatureBuilderParams HolesRelation helper(m_cache); helper.Build(&p); auto const & holesGeometry = helper.GetHoles(); - auto & outer = helper.GetOuter(); auto const size = m_queue.size(); - auto func = [&](FeatureBuilder::PointSeq const & pts, std::vector const & ids) + auto func = [&](FeatureBuilder::PointSeq && pts, std::vector const & ids) { FeatureBuilder fb; + + fb.AssignArea(std::move(pts), holesGeometry); + CHECK(fb.IsGeometryClosed(), ()); + for (uint64_t id : ids) fb.AddOsmId(base::MakeOsmWay(id)); - - for (auto const & pt : pts) - fb.AddPoint(pt); - fb.AddOsmId(base::MakeOsmRelation(p.m_id)); - if (!fb.IsGeometryClosed()) - return; - fb.SetHoles(holesGeometry); fb.SetParams(params); fb.SetArea(); + m_queue.push(std::move(fb)); }; - outer.ForEachArea(true /* collectID */, std::move(func)); + helper.GetOuter().ForEachArea(true /* collectID */, std::move(func)); return size != m_queue.size(); } diff --git a/generator/feature_merger.hpp b/generator/feature_merger.hpp index a7d65f33f1..42ecec0f5b 100644 --- a/generator/feature_merger.hpp +++ b/generator/feature_merger.hpp @@ -28,7 +28,7 @@ public: bool EqualGeometry(MergedFeatureBuilder const & fb) const; - inline bool NotEmpty() const { return !GetOuterGeometry().empty(); } + inline bool NotEmpty() const { return !GetGeometry().empty(); } inline m2::PointD FirstPoint() const { return GetOuterGeometry().front(); } inline m2::PointD LastPoint() const { return GetOuterGeometry().back(); } diff --git a/generator/feature_sorter.cpp b/generator/feature_sorter.cpp index e573f33eff..4ee70b7b72 100644 --- a/generator/feature_sorter.cpp +++ b/generator/feature_sorter.cpp @@ -151,6 +151,8 @@ public: GeometryHolder holder([this](int i) -> FileWriter & { return *m_geoFile[i]; }, [this](int i) -> FileWriter & { return *m_trgFile[i]; }, fb, m_header); + if (!fb.IsPoint()) + { bool const isLine = fb.IsLine(); bool const isArea = fb.IsArea(); CHECK(!isLine || !isArea, ("A feature can't have both points and triangles geometries:", fb.GetMostGenericOsmId())); @@ -233,6 +235,7 @@ public: } } } + } uint32_t featureId = kInvalidFeatureId; auto & buffer = holder.GetBuffer(); diff --git a/generator/generator_tests/affiliation_tests.cpp b/generator/generator_tests/affiliation_tests.cpp index fdd26bdbfa..018cd79e52 100644 --- a/generator/generator_tests/affiliation_tests.cpp +++ b/generator/generator_tests/affiliation_tests.cpp @@ -73,11 +73,10 @@ END)"; std::string const & GetBorderPath() const { return m_testPath; } - static feature::FeatureBuilder MakeLineFb(std::vector const & geom) + static feature::FeatureBuilder MakeLineFb(std::vector && geom) { feature::FeatureBuilder fb; - for (auto const & p : geom) - fb.AddPoint(p); + fb.AssignPoints(std::move(geom)); fb.AddType(classif().GetTypeByPath({"highway", "secondary"})); fb.SetLinear(); diff --git a/generator/generator_tests/cities_ids_tests.cpp b/generator/generator_tests/cities_ids_tests.cpp index e6d200528c..92fa9d8953 100644 --- a/generator/generator_tests/cities_ids_tests.cpp +++ b/generator/generator_tests/cities_ids_tests.cpp @@ -36,33 +36,6 @@ public: DataSource const & GetDataSource() const { return m_dataSource; } }; -// A feature that is big enough for World.mwm but is not a locality. -class TestSea : public TestFeature -{ -public: - TestSea(m2::PointD const & center, std::string const & name, std::string const & lang) - : TestFeature(center, name, lang), m_name(name) - { - } - - // TestFeature overrides: - void Serialize(feature::FeatureBuilder & fb) const - { - TestFeature::Serialize(fb); - fb.AddType(classif().GetTypeByPath({"place", "sea"})); - } - - std::string ToDebugString() const - { - std::ostringstream oss; - oss << "TestSea [" << m_name << "]"; - return oss.str(); - } - -private: - std::string m_name; -}; - UNIT_CLASS_TEST(CitiesIdsTest, BuildCitiesIds) { TestCity paris(m2::PointD(0, 0), "Paris", "fr", 100 /* rank */); diff --git a/generator/generator_tests/collector_city_area_tests.cpp b/generator/generator_tests/collector_city_area_tests.cpp index ee051397b2..44a7b77370 100644 --- a/generator/generator_tests/collector_city_area_tests.cpp +++ b/generator/generator_tests/collector_city_area_tests.cpp @@ -28,9 +28,8 @@ feature::FeatureBuilder MakeFbForTest(OsmElement element) { feature::FeatureBuilder result; ftype::GetNameAndType(&element, result.GetParams()); - std::vector polygon = {{0, 0}, {0, 2}, {2, 2}, {2, 0}, {0, 0}}; result.SetOsmId(base::MakeOsmRelation(element.m_id)); - result.AddPolygon(polygon); + result.AddPolygon({{0, 0}, {0, 2}, {2, 2}, {2, 0}, {0, 0}}); result.SetArea(); return result; } diff --git a/generator/generator_tests/collector_routing_city_boundaries_tests.cpp b/generator/generator_tests/collector_routing_city_boundaries_tests.cpp index 1a50b53e26..cf954a6d3d 100644 --- a/generator/generator_tests/collector_routing_city_boundaries_tests.cpp +++ b/generator/generator_tests/collector_routing_city_boundaries_tests.cpp @@ -38,15 +38,14 @@ std::vector const kPolygon2 = {{2, 0}, {0, 2}, {2, 2}, {2, 0}, {0, 0 std::vector const kPolygon3 = {{3, 0}, {0, 2}, {2, 2}, {2, 0}, {0, 0}, {3, 0}}; std::vector const kPolygon4 = {{4, 0}, {0, 2}, {2, 2}, {2, 0}, {0, 0}, {4, 0}}; -feature::FeatureBuilder MakeAreaFeatureBuilder(OsmElement element, - std::vector const & geometry) +feature::FeatureBuilder MakeAreaFeatureBuilder(OsmElement element, std::vector && geometry) { feature::FeatureBuilder result; auto const filterType = [](uint32_t) { return true; }; ftype::GetNameAndType(&element, result.GetParams(), filterType); result.SetOsmId(base::MakeOsmRelation(element.m_id)); - auto polygon = geometry; - result.AddPolygon(polygon); + + result.AddPolygon(std::move(geometry)); result.SetArea(); return result; } @@ -84,13 +83,13 @@ auto const relationWithLabel3 = MakeAreaWithPlaceNode(7 /* id */, 11 /* placeId auto const relationWithLabel4 = MakeAreaWithPlaceNode(8 /* id */, 12 /* placeId */, "country" /* role */); void Collect(BoundariesCollector & collector, std::vector const & elements, - std::vector> const & geometries = {}) + std::vector> geometries = {}) { for (size_t i = 0; i < elements.size(); ++i) { auto const & element = elements[i]; auto featureBuilder = element.IsNode() ? MakeNodeFeatureBuilder(element) - : MakeAreaFeatureBuilder(element, geometries[i]); + : MakeAreaFeatureBuilder(element, std::move(geometries[i])); if (BoundariesCollector::FilterOsmElement(element)) collector.Process(featureBuilder, element); diff --git a/generator/generator_tests/cross_mwm_osm_ways_collector_tests.cpp b/generator/generator_tests/cross_mwm_osm_ways_collector_tests.cpp index 858d79e340..feb0874e85 100644 --- a/generator/generator_tests/cross_mwm_osm_ways_collector_tests.cpp +++ b/generator/generator_tests/cross_mwm_osm_ways_collector_tests.cpp @@ -117,13 +117,18 @@ public: } }; -feature::FeatureBuilder CreateFeatureBuilderFromOsmWay(uint64_t osmId, std::vector const & points) +feature::FeatureBuilder CreateFeatureBuilderFromOsmWay(uint64_t osmId, std::vector const & llPoints) { feature::FeatureBuilder fb; fb.AddOsmId(base::MakeOsmWay(osmId)); + + std::vector points; + base::Transform(llPoints, std::back_inserter(points), [](ms::LatLon const & ll) + { + return mercator::FromLatLon(ll); + }); + fb.AssignPoints(std::move(points)); fb.SetLinear(); - for (auto const & ll : points) - fb.AddPoint(mercator::FromLatLon(ll)); fb.AddType(classif().GetTypeByPath(kHighwayUnclassifiedPath)); return fb; diff --git a/generator/generator_tests/feature_builder_test.cpp b/generator/generator_tests/feature_builder_test.cpp index e2a2cc5354..205bdf2f69 100644 --- a/generator/generator_tests/feature_builder_test.cpp +++ b/generator/generator_tests/feature_builder_test.cpp @@ -77,8 +77,7 @@ UNIT_CLASS_TEST(TestWithClassificator, FBuilder_LineTypes) params.FinishAddingTypes(); fb1.SetParams(params); - fb1.AddPoint(m2::PointD(0, 0)); - fb1.AddPoint(m2::PointD(1, 1)); + fb1.AssignPoints({ {0, 0}, {1, 1} }); fb1.SetLinear(); TEST(fb1.RemoveInvalidTypes(), ()); @@ -183,8 +182,7 @@ UNIT_CLASS_TEST(TestWithClassificator, FBuilder_RemoveUselessNames) FeatureBuilder fb1; fb1.SetParams(params); - fb1.AddPoint(m2::PointD(0, 0)); - fb1.AddPoint(m2::PointD(1, 1)); + fb1.AssignPoints({ {0, 0}, {1, 1} }); fb1.SetLinear(); TEST(!fb1.GetName(0).empty(), ()); @@ -244,7 +242,6 @@ UNIT_CLASS_TEST(TestWithClassificator, FBuilder_SerializeLocalityObjectForBuildi auto & buffer = holder.GetBuffer(); TEST(fb.PreSerializeAndRemoveUselessNamesForMwm(buffer), ()); - fb.SerializeLocalityObject(serial::GeometryCodingParams(), buffer); } UNIT_CLASS_TEST(TestWithClassificator, FBuilder_SerializeAccuratelyForIntermediate) @@ -265,9 +262,11 @@ UNIT_CLASS_TEST(TestWithClassificator, FBuilder_SerializeAccuratelyForIntermedia fb1.SetParams(params); auto const diff = 0.33333333334567; + std::vector points; for (size_t i = 0; i < 100; ++i) - fb1.AddPoint(m2::PointD(i + diff, i + 1 + diff)); + points.push_back({ i + diff, i + 1 + diff }); + fb1.AssignPoints(std::move(points)); fb1.SetLinear(); TEST(fb1.RemoveInvalidTypes(), ()); diff --git a/generator/generator_tests/feature_merger_test.cpp b/generator/generator_tests/feature_merger_test.cpp index cfeeeda821..8e6877cd0c 100644 --- a/generator/generator_tests/feature_merger_test.cpp +++ b/generator/generator_tests/feature_merger_test.cpp @@ -49,8 +49,7 @@ UNIT_TEST(FeatureMerger_MultipleTypes) for (size_t i = 0; i < count; ++i) { arrF[i].SetLinear(); - arrF[i].AddPoint(arrPt[i]); - arrF[i].AddPoint(arrPt[i+1]); + arrF[i].AssignPoints({ arrPt[i], arrPt[i+1] }); arrF[i].AddType(0); } @@ -97,36 +96,28 @@ UNIT_TEST(FeatureMerger_Branches) std::vector vF; vF.push_back(FeatureBuilder()); - vF.back().AddPoint(P(-2, 0)); - vF.back().AddPoint(P(-1, 0)); + vF.back().AssignPoints({ P(-2, 0), P(-1, 0) }); vF.push_back(FeatureBuilder()); - vF.back().AddPoint(P(-1, 0)); - vF.back().AddPoint(P(0, 1)); + vF.back().AssignPoints({ P(-1, 0), P(0, 1) }); vF.push_back(FeatureBuilder()); - vF.back().AddPoint(P(-1, 0)); - vF.back().AddPoint(P(0, 0)); + vF.back().AssignPoints({ P(-1, 0), P(0, 0) }); vF.push_back(FeatureBuilder()); - vF.back().AddPoint(P(-1, 0)); - vF.back().AddPoint(P(0, -1)); + vF.back().AssignPoints({ P(-1, 0), P(0, -1) }); vF.push_back(FeatureBuilder()); - vF.back().AddPoint(P(0, 1)); - vF.back().AddPoint(P(1, 0)); + vF.back().AssignPoints({ P(0, 1), P(1, 0) }); vF.push_back(FeatureBuilder()); - vF.back().AddPoint(P(0, 0)); - vF.back().AddPoint(P(1, 0)); + vF.back().AssignPoints({ P(0, 0), P(1, 0) }); vF.push_back(FeatureBuilder()); - vF.back().AddPoint(P(0, -1)); - vF.back().AddPoint(P(1, 0)); + vF.back().AssignPoints({ P(0, -1), P(1, 0) }); vF.push_back(FeatureBuilder()); - vF.back().AddPoint(P(1, 0)); - vF.back().AddPoint(P(2, 0)); + vF.back().AssignPoints({ P(1, 0), P(2, 0) }); FeatureMergeProcessor processor(kPointCoordBits); @@ -151,32 +142,21 @@ UNIT_TEST(FeatureMerger_Rounds) std::vector vF; vF.push_back(FeatureBuilder()); - vF.back().AddPoint(P(-10, 0)); - vF.back().AddPoint(P(-5, 0)); + vF.back().AssignPoints({ P(-10, 0), P(-5, 0) }); // make first round feature vF.push_back(FeatureBuilder()); - vF.back().AddPoint(P(-4, 1)); - vF.back().AddPoint(P(-3, 0)); - vF.back().AddPoint(P(-4, -1)); - vF.back().AddPoint(P(-5, 0)); - vF.back().AddPoint(P(-4, 1)); + vF.back().AssignPoints({ P(-4, 1), P(-3, 0), P(-4, -1), P(-5, 0), P(-4, 1) }); vF.push_back(FeatureBuilder()); - vF.back().AddPoint(P(-3, 0)); - vF.back().AddPoint(P(3, 0)); + vF.back().AssignPoints({ P(-3, 0), P(3, 0) }); // make second round feature vF.push_back(FeatureBuilder()); - vF.back().AddPoint(P(4, -1)); - vF.back().AddPoint(P(3, 0)); - vF.back().AddPoint(P(4, 1)); - vF.back().AddPoint(P(5, 0)); - vF.back().AddPoint(P(4, -1)); + vF.back().AssignPoints({ P(4, -1), P(3, 0), P(4, 1), P(5, 0), P(4, -1) }); vF.push_back(FeatureBuilder()); - vF.back().AddPoint(P(5, 0)); - vF.back().AddPoint(P(10, 0)); + vF.back().AssignPoints({ P(5, 0), P(10, 0) }); FeatureMergeProcessor processor(kPointCoordBits); diff --git a/generator/generator_tests/hierarchy_tests.cpp b/generator/generator_tests/hierarchy_tests.cpp index 8d896a6e99..932e29cdbb 100644 --- a/generator/generator_tests/hierarchy_tests.cpp +++ b/generator/generator_tests/hierarchy_tests.cpp @@ -21,8 +21,7 @@ std::vector MakeTestSet1() std::vector fbs; { feature::FeatureBuilder outline; - std::vector polygon = {{0.0, 0.0}, {0.0, 10.0}, {10.0, 10.0}, {10.0, 0.0}}; - outline.AddPolygon(polygon); + outline.AddPolygon({{0.0, 0.0}, {0.0, 10.0}, {10.0, 10.0}, {10.0, 0.0}}); outline.AddOsmId(base::MakeOsmWay(1)); outline.AddType(classif().GetTypeByPath({"building"})); outline.AddType(classif().GetTypeByPath({"tourism", "attraction"})); @@ -31,8 +30,7 @@ std::vector MakeTestSet1() } { feature::FeatureBuilder buildingPart; - std::vector polygon = {{0.0, 0.0}, {0.0, 8.0}, {8.0, 8.0}, {8.0, 0.0}}; - buildingPart.AddPolygon(polygon); + buildingPart.AddPolygon({{0.0, 0.0}, {0.0, 8.0}, {8.0, 8.0}, {8.0, 0.0}}); buildingPart.AddOsmId(base::MakeOsmWay(2)); buildingPart.AddType(classif().GetTypeByPath({"building:part"})); buildingPart.SetArea(); @@ -40,8 +38,7 @@ std::vector MakeTestSet1() } { feature::FeatureBuilder buildingPart; - std::vector polygon = {{0.0, 0.0}, {0.0, 7.0}, {7.0, 7.0}, {7.0, 0.0}}; - buildingPart.AddPolygon(polygon); + buildingPart.AddPolygon({{0.0, 0.0}, {0.0, 7.0}, {7.0, 7.0}, {7.0, 0.0}}); buildingPart.AddOsmId(base::MakeOsmWay(3)); buildingPart.AddType(classif().GetTypeByPath({"building:part"})); buildingPart.SetArea(); @@ -49,8 +46,7 @@ std::vector MakeTestSet1() } { feature::FeatureBuilder buildingPart; - std::vector polygon = {{0.0, 0.0}, {0.0, 6.0}, {6.0, 6.0}, {6.0, 0.0}}; - buildingPart.AddPolygon(polygon); + buildingPart.AddPolygon({{0.0, 0.0}, {0.0, 6.0}, {6.0, 6.0}, {6.0, 0.0}}); buildingPart.AddOsmId(base::MakeOsmWay(4)); buildingPart.AddType(classif().GetTypeByPath({"building:part"})); buildingPart.SetArea(); @@ -106,8 +102,7 @@ UNIT_CLASS_TEST(TestWithClassificator, ComplexHierarchy_AddChildrenTo) if (compositeId.m_mainId == osmId) { feature::FeatureBuilder buildingPart; - std::vector polygon = {{6.0, 6.0}, {6.0, 7.0}, {7.0, 7.0}, {7.0, 6.0}}; - buildingPart.AddPolygon(polygon); + buildingPart.AddPolygon({{6.0, 6.0}, {6.0, 7.0}, {7.0, 7.0}, {7.0, 6.0}}); buildingPart.AddOsmId(base::MakeOsmWay(5)); buildingPart.AddType(classif().GetTypeByPath({"building:part"})); buildingPart.SetArea(); diff --git a/generator/generator_tests/place_processor_tests.cpp b/generator/generator_tests/place_processor_tests.cpp index efcbb6e409..45cfc7885f 100644 --- a/generator/generator_tests/place_processor_tests.cpp +++ b/generator/generator_tests/place_processor_tests.cpp @@ -52,7 +52,7 @@ struct DisablerIdInc }; feature::FeatureBuilder MakeFbForTest(generator_tests::Tags const & tags, OsmElement::EntityType t, - std::vector const & points) + std::vector && points) { auto element = generator_tests::MakeOsmElement(GetIdGen().GetId(), tags, t); feature::FeatureBuilder result; @@ -65,11 +65,8 @@ feature::FeatureBuilder MakeFbForTest(generator_tests::Tags const & tags, OsmEle } else if (element.IsRelation() || element.IsWay()) { - for (auto const & p : points) - result.AddPoint(p); - + result.AssignPoints(std::move(points)); CHECK(result.IsGeometryClosed(), ()); - result.SetArea(); result.SetOsmId(element.IsRelation() ? base::MakeOsmRelation(element.m_id) diff --git a/generator/generator_tests_support/test_feature.cpp b/generator/generator_tests_support/test_feature.cpp index 23ec088e7e..18433c3f9d 100644 --- a/generator/generator_tests_support/test_feature.cpp +++ b/generator/generator_tests_support/test_feature.cpp @@ -39,55 +39,45 @@ vector MakePoly(m2::RectD const & rect) { return { rect.LeftBottom(), rect.RightBottom(), rect.RightTop(), rect.LeftTop(), rect.LeftBottom() }; } + +StringUtf8Multilang MakeName(string const & name, string const & lang) +{ + StringUtf8Multilang res; + res.AddString(lang, name); + + // Names used for search depend on locale. Fill default name because we need to run tests with + // different locales. If you do not need default name to be filled use + // TestFeature::TestFeature(StringUtf8Multilang const & name). + res.AddString("default", name); + return res; +} } // namespace // TestFeature ------------------------------------------------------------------------------------- TestFeature::TestFeature() : m_id(GenUniqueId()), m_center(0, 0), m_type(Type::Unknown) { Init(); } -TestFeature::TestFeature(string const & name, string const & lang) - : m_id(GenUniqueId()), m_center(0, 0), m_type(Type::Unknown) -{ - m_names.AddString(lang, name); - - // Names used for search depend on locale. Fill default name because we need to run tests with - // different locales. If you do not need default name to be filled use - // TestFeature::TestFeature(StringUtf8Multilang const & name). - m_names.AddString("default", name); - Init(); -} - -TestFeature::TestFeature(StringUtf8Multilang const & name) - : m_id(GenUniqueId()), m_center(0, 0), m_type(Type::Unknown), m_names(name) +TestFeature::TestFeature(StringUtf8Multilang name) + : m_id(GenUniqueId()), m_center(0, 0), m_type(Type::Unknown), m_names(std::move(name)) { Init(); } -TestFeature::TestFeature(m2::PointD const & center, string const & name, string const & lang) - : m_id(GenUniqueId()), m_center(center), m_type(Type::Point) -{ - m_names.AddString(lang, name); - m_names.AddString("default", name); - Init(); -} - -TestFeature::TestFeature(m2::PointD const & center, StringUtf8Multilang const & name) - : m_id(GenUniqueId()), m_center(center), m_type(Type::Point), m_names(name) +TestFeature::TestFeature(m2::PointD const & center, StringUtf8Multilang name) + : m_id(GenUniqueId()), m_center(center), m_type(Type::Point), m_names(std::move(name)) { Init(); } -TestFeature::TestFeature(m2::RectD const & boundary, string const & name, string const & lang) - : TestFeature(MakePoly(boundary), name, lang) +TestFeature::TestFeature(m2::RectD const & boundary, StringUtf8Multilang name) + : TestFeature(MakePoly(boundary), std::move(name), Type::Area) { Init(); } -TestFeature::TestFeature(vector const & boundary, string const & name, string const & lang) - : m_id(GenUniqueId()), m_center(0, 0), m_boundary(boundary), m_type(Type::Area) +TestFeature::TestFeature(vector geometry, StringUtf8Multilang name, Type type) + : m_id(GenUniqueId()), m_center(0, 0), m_geometry(std::move(geometry)), m_type(type), m_names(std::move(name)) { - m_names.AddString(lang, name); - m_names.AddString("default", name); - ASSERT(!m_boundary.empty(), ()); + ASSERT(!m_geometry.empty(), ()); Init(); } @@ -121,6 +111,9 @@ void TestFeature::Serialize(FeatureBuilder & fb) const fb.GetMetadata().Set(type, string(m_metadata.Get(type))); } + if (!m_geometry.empty()) + fb.AssignPoints(m_geometry); + switch (m_type) { case Type::Point: @@ -128,11 +121,13 @@ void TestFeature::Serialize(FeatureBuilder & fb) const fb.SetCenter(m_center); break; } + case Type::Line: + { + fb.SetLinear(); + break; + } case Type::Area: { - ASSERT(!m_boundary.empty(), ()); - for (auto const & p : m_boundary) - fb.AddPoint(p); fb.SetArea(); break; } @@ -155,7 +150,7 @@ void TestFeature::Serialize(FeatureBuilder & fb) const // TestPlace ------------------------------------------------------------------------------------- TestPlace::TestPlace(m2::PointD const & center, string const & name, string const & lang, uint32_t type, uint8_t rank /* = 0 */) - : TestFeature(center, name, lang), m_type(type), m_rank(rank) + : TestFeature(center, MakeName(name, lang)), m_type(type), m_rank(rank) { } @@ -167,7 +162,7 @@ TestPlace::TestPlace(m2::PointD const & center, StringUtf8Multilang const & name TestPlace::TestPlace(std::vector const & boundary, std::string const & name, std::string const & lang, uint32_t type, uint8_t rank) - : TestFeature(boundary, name, lang), m_type(type), m_rank(rank) + : TestFeature(boundary, MakeName(name, lang), Type::Area), m_type(type), m_rank(rank) { } @@ -195,6 +190,11 @@ TestState::TestState(m2::PointD const & center, string const & name, string cons { } +TestSea::TestSea(m2::PointD const & center, std::string const & name, std::string const & lang) + : TestPlace(center, name, lang, classif().GetTypeByPath({"place", "sea"})) +{ +} + uint32_t TestCity::GetCityType() { return classif().GetTypeByPath({"place", "city"}); @@ -222,13 +222,13 @@ TestVillage::TestVillage(m2::PointD const & center, string const & name, string // TestStreet -------------------------------------------------------------------------------------- TestStreet::TestStreet(vector const & points, string const & name, string const & lang) - : TestFeature(name, lang), m_points(points) + : TestFeature(points, MakeName(name, lang), Type::Line) { SetType({ "highway", "living_street" }); } TestStreet::TestStreet(vector const & points, StringUtf8Multilang const & name) - : TestFeature(name), m_points(points) + : TestFeature(points, name, Type::Line) { SetType({ "highway", "living_street" }); } @@ -245,22 +245,18 @@ void TestStreet::Serialize(FeatureBuilder & fb) const fb.SetType(m_highwayType); fb.GetParams().ref = m_roadNumber; - - for (auto const & point : m_points) - fb.AddPoint(point); - fb.SetLinear(false /* reverseGeometry */); } string TestStreet::ToDebugString() const { ostringstream os; - os << "TestStreet [" << DebugPrint(m_names) << ", " << ::DebugPrint(m_points) << "]"; + os << "TestStreet [" << DebugPrint(m_names) << ", " << ::DebugPrint(m_geometry) << "]"; return os.str(); } // TestSquare -------------------------------------------------------------------------------------- TestSquare::TestSquare(m2::RectD const & rect, string const & name, string const & lang) - : TestFeature(rect, name, lang) + : TestFeature(rect, MakeName(name, lang)) { } @@ -281,7 +277,7 @@ string TestSquare::ToDebugString() const // TestPOI ----------------------------------------------------------------------------------------- TestPOI::TestPOI(m2::PointD const & center, string const & name, string const & lang) - : TestFeature(center, name, lang) + : TestFeature(center, MakeName(name, lang)) { SetTypes({{"railway", "station"}}); } @@ -382,19 +378,19 @@ string TestMultilingualPOI::ToDebugString() const // TestBuilding ------------------------------------------------------------------------------------ TestBuilding::TestBuilding(m2::PointD const & center, string const & name, string const & houseNumber, string const & lang) - : TestFeature(center, name, lang), m_houseNumber(houseNumber) + : TestFeature(center, MakeName(name, lang)), m_houseNumber(houseNumber) { } TestBuilding::TestBuilding(m2::PointD const & center, string const & name, string const & houseNumber, string_view street, string const & lang) - : TestFeature(center, name, lang), m_houseNumber(houseNumber), m_streetName(street) + : TestFeature(center, MakeName(name, lang)), m_houseNumber(houseNumber), m_streetName(street) { } TestBuilding::TestBuilding(m2::RectD const & boundary, string const & name, string const & houseNumber, string_view street, string const & lang) - : TestFeature(boundary, name, lang) + : TestFeature(boundary, MakeName(name, lang)) , m_houseNumber(houseNumber) , m_streetName(street) { @@ -426,16 +422,13 @@ string TestBuilding::ToDebugString() const // TestPark ---------------------------------------------------------------------------------------- TestPark::TestPark(vector const & boundary, string const & name, string const & lang) - : TestFeature(boundary, name, lang) + : TestFeature(boundary, MakeName(name, lang), Type::Area) { } void TestPark::Serialize(FeatureBuilder & fb) const { TestFeature::Serialize(fb); - for (auto const & point : m_boundary) - fb.AddPoint(point); - fb.SetArea(); auto const & classificator = classif(); fb.AddType(classificator.GetTypeByPath({"leisure", "park"})); @@ -451,7 +444,7 @@ string TestPark::ToDebugString() const // TestRoad ---------------------------------------------------------------------------------------- TestRoad::TestRoad(vector const & points, string const & name, string const & lang) - : TestFeature(name, lang), m_points(points) + : TestFeature(points, MakeName(name, lang), Type::Line) { } @@ -461,10 +454,6 @@ void TestRoad::Serialize(FeatureBuilder & fb) const auto const & classificator = classif(); fb.AddType(classificator.GetTypeByPath({"highway", "road"})); - - for (auto const & point : m_points) - fb.AddPoint(point); - fb.SetLinear(false /* reverseGeometry */); } string TestRoad::ToDebugString() const diff --git a/generator/generator_tests_support/test_feature.hpp b/generator/generator_tests_support/test_feature.hpp index ab87b31755..47d2fb5e9e 100644 --- a/generator/generator_tests_support/test_feature.hpp +++ b/generator/generator_tests_support/test_feature.hpp @@ -50,21 +50,20 @@ protected: enum class Type { Point, + Line, Area, Unknown }; TestFeature(); - TestFeature(std::string const & name, std::string const & lang); - TestFeature(StringUtf8Multilang const & name); - TestFeature(m2::PointD const & center, std::string const & name, std::string const & lang); - TestFeature(m2::PointD const & center, StringUtf8Multilang const & name); - TestFeature(m2::RectD const & boundary, std::string const & name, std::string const & lang); - TestFeature(std::vector const & boundary, std::string const & name, std::string const & lang); + explicit TestFeature(StringUtf8Multilang name); + TestFeature(m2::PointD const & center, StringUtf8Multilang name); + TestFeature(m2::RectD const & boundary, StringUtf8Multilang name); + TestFeature(std::vector geometry, StringUtf8Multilang name, Type type); uint64_t const m_id; m2::PointD const m_center; - std::vector const m_boundary; + std::vector const m_geometry; Type const m_type; StringUtf8Multilang m_names; std::string m_postcode; @@ -105,6 +104,13 @@ public: TestState(m2::PointD const & center, std::string const & name, std::string const & lang); }; +// A feature that is big enough for World.mwm but is not a locality. +class TestSea : public TestPlace +{ +public: + TestSea(m2::PointD const & center, std::string const & name, std::string const & lang); +}; + class TestCity : public TestPlace { static uint32_t GetCityType(); @@ -134,7 +140,6 @@ public: std::string ToDebugString() const override; private: - std::vector m_points; uint32_t m_highwayType; std::string m_roadNumber; }; @@ -229,9 +234,6 @@ public: // TestFeature overrides: void Serialize(feature::FeatureBuilder & fb) const override; std::string ToDebugString() const override; - -private: - std::vector m_points; }; std::string DebugPrint(TestFeature const & feature); diff --git a/generator/isolines_generator.cpp b/generator/isolines_generator.cpp index 3a206cc883..ca6a20baa1 100644 --- a/generator/isolines_generator.cpp +++ b/generator/isolines_generator.cpp @@ -67,7 +67,7 @@ void IsolineFeaturesGenerator::GenerateIsolines(std::string const & countryName, return; } LOG(LINFO, ("Generating isolines for", countryName)); - for (auto const & levelIsolines : countryIsolines.m_contours) + for (auto & levelIsolines : countryIsolines.m_contours) { auto const altitude = levelIsolines.first; auto const isolineName = GetIsolineName(altitude, countryIsolines.m_valueStep, @@ -79,14 +79,15 @@ void IsolineFeaturesGenerator::GenerateIsolines(std::string const & countryName, continue; } - for (auto const & isoline : levelIsolines.second) + for (auto & isoline : levelIsolines.second) { feature::FeatureBuilder fb; - for (auto const & pt : isoline) - fb.AddPoint(pt); + fb.AssignPoints(std::move(isoline)); + fb.AddType(isolineType); if (!isolineName.empty()) fb.AddName("default", isolineName); + fb.SetLinear(); fn(std::move(fb)); } diff --git a/generator/mini_roundabout_transformer.cpp b/generator/mini_roundabout_transformer.cpp index ac5e5912b7..cb94f716a4 100644 --- a/generator/mini_roundabout_transformer.cpp +++ b/generator/mini_roundabout_transformer.cpp @@ -43,14 +43,6 @@ bool MoveIterAwayFromRoundabout(feature::FeatureBuilder::PointSeq::iterator & it return middlePoint; } -void UpdateFeatureGeometry(feature::FeatureBuilder::PointSeq const & seq, - feature::FeatureBuilder & fb) -{ - fb.ResetGeometry(); - for (auto const & p : seq) - fb.AddPoint(p); -} - feature::FeatureBuilder::PointSeq::iterator GetIterOnRoad(m2::PointD const & point, feature::FeatureBuilder::PointSeq & road) { @@ -137,7 +129,7 @@ void MiniRoundaboutTransformer::UpdateRoadType(FeatureParams::Types const & foun } } -feature::FeatureBuilder CreateFb(std::vector const & way, uint64_t id, +feature::FeatureBuilder CreateFb(std::vector && way, uint64_t id, uint32_t roadType, bool isRoundabout = true, bool isLeftHandTraffic = false) { @@ -147,23 +139,15 @@ feature::FeatureBuilder CreateFb(std::vector const & way, uint64_t i if (!isRoundabout) { - UpdateFeatureGeometry(way, fb); + fb.AssignPoints(std::move(way)); return fb; } if (isLeftHandTraffic) - { - std::vector wayRev = way; - std::reverse(wayRev.begin(), wayRev.end()); + std::reverse(way.begin(), way.end()); - UpdateFeatureGeometry(wayRev, fb); - fb.AddPoint(wayRev[0]); - } - else - { - UpdateFeatureGeometry(way, fb); - fb.AddPoint(way[0]); - } + way.push_back(way[0]); + fb.AssignPoints(std::move(way)); static uint32_t const roundaboutType = classif().GetTypeByPath({"junction", "roundabout"}); fb.AddType(roundaboutType); @@ -220,12 +204,12 @@ bool MiniRoundaboutTransformer::AddRoundaboutToRoad(RoundaboutUnit const & round if (isMiddlePoint) { - auto const surrogateRoad = + auto surrogateRoad = CreateSurrogateRoad(roundaboutOnRoad, roundaboutCircle, road, itPointUpd); if (surrogateRoad.size() < 2) return false; auto fbSurrogateRoad = - CreateFb(surrogateRoad, roundaboutOnRoad.m_roadId, 0, false /* isRoundabout */); + CreateFb(std::move(surrogateRoad), roundaboutOnRoad.m_roadId, 0, false /* isRoundabout */); for (auto const & t : roundaboutOnRoad.m_roadTypes) fbSurrogateRoad.AddType(t); @@ -320,7 +304,7 @@ std::vector MiniRoundaboutTransformer::ProcessRoundabou if (!AddRoundaboutToRoad(roundaboutOnRoad, circlePlain, road, fbsRoads)) continue; - UpdateFeatureGeometry(road, *itRoad); + itRoad->AssignPoints(std::move(road)); UpdateRoadType(itRoad->GetTypes(), roadType); foundRoad = true; } @@ -329,7 +313,7 @@ std::vector MiniRoundaboutTransformer::ProcessRoundabou continue; fbsRoundabouts.push_back( - CreateFb(circlePlain, rb.m_id, roadType, true /* isRoundabout */, m_leftHandTraffic)); + CreateFb(std::move(circlePlain), rb.m_id, roadType, true /* isRoundabout */, m_leftHandTraffic)); } LOG(LINFO, ("Transformed", fbsRoundabouts.size(), "mini_roundabouts to roundabouts.", "Added", diff --git a/generator/water_boundary_checker.hpp b/generator/water_boundary_checker.hpp index be3728cd03..7472725a81 100644 --- a/generator/water_boundary_checker.hpp +++ b/generator/water_boundary_checker.hpp @@ -23,13 +23,13 @@ class WaterBoundaryChecker public: ~WaterBoundaryChecker() { - LOG_SHORT(LINFO, ("Features checked:", m_totalFeatures, "borders checked:", m_totalBorders, + LOG(LINFO, ("Features checked:", m_totalFeatures, "borders checked:", m_totalBorders, "borders skipped:", m_skippedBorders, "selected polygons:", m_selectedPolygons)); } void LoadWaterGeometry(std::string const & rawGeometryFileName) { - LOG_SHORT(LINFO, ("Loading water geometry:", rawGeometryFileName)); + LOG(LINFO, ("Loading water geometry:", rawGeometryFileName)); FileReader reader(rawGeometryFileName); ReaderSource file(reader); @@ -54,19 +54,18 @@ public: m_tree.Add(m2::RegionD(std::move(points))); } } - LOG_SHORT(LINFO, ("Load", total, "water geometries")); + LOG(LINFO, ("Load", total, "water geometries")); } bool IsBoundaries(feature::FeatureBuilder const & fb) { ++m_totalFeatures; - auto static const kBoundaryType = classif().GetTypeByPath({"boundary", "administrative"}); - if (fb.FindType(kBoundaryType, 2) == ftype::GetEmptyValue()) + static uint32_t const kBoundaryType = classif().GetTypeByPath({"boundary", "administrative"}); + if (!fb.IsLine() || !fb.HasType(kBoundaryType, 2)) return false; ++m_totalBorders; - return true; } @@ -79,16 +78,13 @@ public: void ProcessBoundary(feature::FeatureBuilder const & boundary, std::vector & parts) { - auto const & line = boundary.GetGeometry().front(); - double constexpr kExtension = 0.01; ProcessState state = ProcessState::Initial; feature::FeatureBuilder::PointSeq points; - for (size_t i = 0; i < line.size(); ++i) + for (auto const & p : boundary.GetOuterGeometry()) { - m2::PointD const & p = line[i]; m2::RectD r(p.x - kExtension, p.y - kExtension, p.x + kExtension, p.y + kExtension); size_t hits = 0; m_tree.ForEachInRect(r, [&](m2::RegionD const & rgn) @@ -134,9 +130,7 @@ public: if (points.size() > 1) { parts.push_back(boundary); - parts.back().ResetGeometry(); - for (auto const & pt : points) - parts.back().AddPoint(pt); + parts.back().AssignPoints(std::move(points)); } points.clear(); state = ProcessState::Water; @@ -153,9 +147,7 @@ public: if (points.size() > 1) { parts.push_back(boundary); - parts.back().ResetGeometry(); - for (auto const & pt : points) - parts.back().AddPoint(pt); + parts.back().AssignPoints(std::move(points)); } if (parts.empty()) diff --git a/generator/ways_merger.hpp b/generator/ways_merger.hpp index ff12ecaa38..446af209ac 100644 --- a/generator/ways_merger.hpp +++ b/generator/ways_merger.hpp @@ -71,7 +71,7 @@ public: } while (true); if (points.size() > 2 && points.front() == points.back()) - toDo(points, ids); + toDo(std::move(points), ids); } }