From adc138c7a8477e447e0a477ea87821e453548905 Mon Sep 17 00:00:00 2001 From: Alexander Shalamov Date: Tue, 23 Jul 2019 08:54:16 +0300 Subject: [PATCH 1/4] [core] Force getGeometries() return const ref --- .../benchmark/stub_geometry_tile_feature.hpp | 2 +- src/mbgl/annotation/annotation_tile.cpp | 2 +- src/mbgl/annotation/annotation_tile.hpp | 2 +- src/mbgl/geometry/feature_index.cpp | 2 +- src/mbgl/layout/symbol_feature.hpp | 2 +- .../renderer/layers/render_circle_layer.cpp | 2 +- src/mbgl/style/expression/expression.cpp | 4 +++- src/mbgl/tile/geojson_tile_data.hpp | 18 +++++++++++------- src/mbgl/tile/geometry_tile.cpp | 2 +- src/mbgl/tile/geometry_tile_data.cpp | 2 +- src/mbgl/tile/geometry_tile_data.hpp | 2 +- src/mbgl/tile/vector_tile_data.cpp | 15 ++++++++------- src/mbgl/tile/vector_tile_data.hpp | 3 ++- .../mbgl/test/stub_geometry_tile_feature.hpp | 2 +- 14 files changed, 34 insertions(+), 26 deletions(-) diff --git a/benchmark/src/mbgl/benchmark/stub_geometry_tile_feature.hpp b/benchmark/src/mbgl/benchmark/stub_geometry_tile_feature.hpp index bff1a23ba8a..b8f2ffb5b9a 100644 --- a/benchmark/src/mbgl/benchmark/stub_geometry_tile_feature.hpp +++ b/benchmark/src/mbgl/benchmark/stub_geometry_tile_feature.hpp @@ -35,7 +35,7 @@ class StubGeometryTileFeature : public GeometryTileFeature { return properties.count(key) ? properties.at(key) : optional(); } - GeometryCollection getGeometries() const override { + const GeometryCollection& getGeometries() const override { return geometry; } }; diff --git a/src/mbgl/annotation/annotation_tile.cpp b/src/mbgl/annotation/annotation_tile.cpp index 6c3c9eb617c..a410adc95ee 100644 --- a/src/mbgl/annotation/annotation_tile.cpp +++ b/src/mbgl/annotation/annotation_tile.cpp @@ -58,7 +58,7 @@ FeatureIdentifier AnnotationTileFeature::getID() const { return data->id; } -GeometryCollection AnnotationTileFeature::getGeometries() const { +const GeometryCollection& AnnotationTileFeature::getGeometries() const { return data->geometries; } diff --git a/src/mbgl/annotation/annotation_tile.hpp b/src/mbgl/annotation/annotation_tile.hpp index 1e23fdf98a3..741b598a8cc 100644 --- a/src/mbgl/annotation/annotation_tile.hpp +++ b/src/mbgl/annotation/annotation_tile.hpp @@ -28,7 +28,7 @@ class AnnotationTileFeature : public GeometryTileFeature { FeatureType getType() const override; optional getValue(const std::string&) const override; FeatureIdentifier getID() const override; - GeometryCollection getGeometries() const override; + const GeometryCollection& getGeometries() const override; private: std::shared_ptr data; diff --git a/src/mbgl/geometry/feature_index.cpp b/src/mbgl/geometry/feature_index.cpp index 3675e8bc6ed..b76e02be3f4 100644 --- a/src/mbgl/geometry/feature_index.cpp +++ b/src/mbgl/geometry/feature_index.cpp @@ -159,7 +159,7 @@ void FeatureIndex::addFeature( continue; } - result[layerID].push_back(convertFeature(*geometryTileFeature, tileID)); + result[layerID].emplace_back(convertFeature(*geometryTileFeature, tileID)); } } diff --git a/src/mbgl/layout/symbol_feature.hpp b/src/mbgl/layout/symbol_feature.hpp index 72f613d4b60..2c952fc12ac 100644 --- a/src/mbgl/layout/symbol_feature.hpp +++ b/src/mbgl/layout/symbol_feature.hpp @@ -20,7 +20,7 @@ class SymbolFeature : public GeometryTileFeature { optional getValue(const std::string& key) const override { return feature->getValue(key); }; std::unordered_map getProperties() const override { return feature->getProperties(); }; FeatureIdentifier getID() const override { return feature->getID(); }; - GeometryCollection getGeometries() const override { return geometry; }; + const GeometryCollection& getGeometries() const override { return geometry; }; friend bool operator < (const SymbolFeature& lhs, const SymbolFeature& rhs) { return lhs.sortKey < rhs.sortKey; diff --git a/src/mbgl/renderer/layers/render_circle_layer.cpp b/src/mbgl/renderer/layers/render_circle_layer.cpp index cf593193075..4f1620364f3 100644 --- a/src/mbgl/renderer/layers/render_circle_layer.cpp +++ b/src/mbgl/renderer/layers/render_circle_layer.cpp @@ -167,7 +167,7 @@ bool RenderCircleLayer::queryIntersectsFeature( projectQueryGeometry(translatedQueryGeometry, posMatrix, transformState.getSize()); auto transformedSize = alignWithMap ? size * pixelsToTileUnits : size; - auto geometry = feature.getGeometries(); + const auto& geometry = feature.getGeometries(); for (auto& ring : geometry) { for (auto& point : ring) { const GeometryCoordinate& transformedPoint = alignWithMap ? point : projectPoint(point, posMatrix, transformState.getSize()); diff --git a/src/mbgl/style/expression/expression.cpp b/src/mbgl/style/expression/expression.cpp index 1e5b1581d25..4800f6aa7f6 100644 --- a/src/mbgl/style/expression/expression.cpp +++ b/src/mbgl/style/expression/expression.cpp @@ -17,7 +17,7 @@ class GeoJSONFeature : public GeometryTileFeature { } PropertyMap getProperties() const override { return feature.properties; } FeatureIdentifier getID() const override { return feature.id; } - GeometryCollection getGeometries() const override { return {}; } + const GeometryCollection& getGeometries() const override { return geometry; } optional getValue(const std::string& key) const override { auto it = feature.properties.find(key); if (it != feature.properties.end()) { @@ -25,6 +25,8 @@ class GeoJSONFeature : public GeometryTileFeature { } return optional(); } + + GeometryCollection geometry; }; diff --git a/src/mbgl/tile/geojson_tile_data.hpp b/src/mbgl/tile/geojson_tile_data.hpp index 3605af96901..21a65144d95 100644 --- a/src/mbgl/tile/geojson_tile_data.hpp +++ b/src/mbgl/tile/geojson_tile_data.hpp @@ -25,15 +25,17 @@ class GeoJSONTileFeature : public GeometryTileFeature { return feature.id; } - GeometryCollection getGeometries() const override { - GeometryCollection geometry = apply_visitor(ToGeometryCollection(), feature.geometry); - - // https://github.com/mapbox/geojson-vt-cpp/issues/44 - if (getType() == FeatureType::Polygon) { - geometry = fixupPolygons(geometry); + const GeometryCollection& getGeometries() const override { + if (!geometry) { + geometry = apply_visitor(ToGeometryCollection(), feature.geometry); + + // https://github.com/mapbox/geojson-vt-cpp/issues/44 + if (getType() == FeatureType::Polygon) { + geometry = fixupPolygons(*geometry); + } } - return geometry; + return *geometry; } optional getValue(const std::string& key) const override { @@ -43,6 +45,8 @@ class GeoJSONTileFeature : public GeometryTileFeature { } return optional(); } + + mutable optional geometry; }; class GeoJSONTileLayer : public GeometryTileLayer { diff --git a/src/mbgl/tile/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp index 7f1bed49f4a..a431ae423ea 100644 --- a/src/mbgl/tile/geometry_tile.cpp +++ b/src/mbgl/tile/geometry_tile.cpp @@ -360,7 +360,7 @@ void GeometryTile::querySourceFeatures( continue; } - result.push_back(convertFeature(*feature, id.canonical)); + result.emplace_back(convertFeature(*feature, id.canonical)); } } } diff --git a/src/mbgl/tile/geometry_tile_data.cpp b/src/mbgl/tile/geometry_tile_data.cpp index 680f8d1497b..2dda9ecae4d 100644 --- a/src/mbgl/tile/geometry_tile_data.cpp +++ b/src/mbgl/tile/geometry_tile_data.cpp @@ -112,7 +112,7 @@ static Feature::geometry_type convertGeometry(const GeometryTileFeature& geometr ); }; - GeometryCollection geometries = geometryTileFeature.getGeometries(); + const GeometryCollection& geometries = geometryTileFeature.getGeometries(); switch (geometryTileFeature.getType()) { case FeatureType::Unknown: { diff --git a/src/mbgl/tile/geometry_tile_data.hpp b/src/mbgl/tile/geometry_tile_data.hpp index 6ce67a532e4..db3378a019d 100644 --- a/src/mbgl/tile/geometry_tile_data.hpp +++ b/src/mbgl/tile/geometry_tile_data.hpp @@ -44,7 +44,7 @@ class GeometryTileFeature { virtual optional getValue(const std::string& key) const = 0; virtual PropertyMap getProperties() const { return PropertyMap(); } virtual FeatureIdentifier getID() const { return NullValue {}; } - virtual GeometryCollection getGeometries() const = 0; + virtual const GeometryCollection& getGeometries() const = 0; }; class GeometryTileLayer { diff --git a/src/mbgl/tile/vector_tile_data.cpp b/src/mbgl/tile/vector_tile_data.cpp index 2d47515e0fe..926e5960803 100644 --- a/src/mbgl/tile/vector_tile_data.cpp +++ b/src/mbgl/tile/vector_tile_data.cpp @@ -34,14 +34,15 @@ FeatureIdentifier VectorTileFeature::getID() const { return feature.getID(); } -GeometryCollection VectorTileFeature::getGeometries() const { - const float scale = float(util::EXTENT) / feature.getExtent(); - auto lines = feature.getGeometries(scale); - if (feature.getVersion() >= 2 || feature.getType() != mapbox::vector_tile::GeomType::POLYGON) { - return lines; - } else { - return fixupPolygons(lines); +const GeometryCollection& VectorTileFeature::getGeometries() const { + if (!lines) { + const float scale = float(util::EXTENT) / feature.getExtent(); + lines = feature.getGeometries(scale); + if (feature.getVersion() < 2 && feature.getType() == mapbox::vector_tile::GeomType::POLYGON) { + lines = fixupPolygons(*lines); + } } + return *lines; } VectorTileLayer::VectorTileLayer(std::shared_ptr data_, diff --git a/src/mbgl/tile/vector_tile_data.hpp b/src/mbgl/tile/vector_tile_data.hpp index 7c95121a37b..525c7935e45 100644 --- a/src/mbgl/tile/vector_tile_data.hpp +++ b/src/mbgl/tile/vector_tile_data.hpp @@ -17,10 +17,11 @@ class VectorTileFeature : public GeometryTileFeature { optional getValue(const std::string& key) const override; std::unordered_map getProperties() const override; FeatureIdentifier getID() const override; - GeometryCollection getGeometries() const override; + const GeometryCollection& getGeometries() const override; private: mapbox::vector_tile::feature feature; + mutable optional lines; }; class VectorTileLayer : public GeometryTileLayer { diff --git a/test/src/mbgl/test/stub_geometry_tile_feature.hpp b/test/src/mbgl/test/stub_geometry_tile_feature.hpp index ef21f8e937e..e74988df2e9 100644 --- a/test/src/mbgl/test/stub_geometry_tile_feature.hpp +++ b/test/src/mbgl/test/stub_geometry_tile_feature.hpp @@ -33,7 +33,7 @@ class StubGeometryTileFeature : public GeometryTileFeature { return properties.count(key) ? properties.at(key) : optional(); } - GeometryCollection getGeometries() const override { + const GeometryCollection& getGeometries() const override { return geometry; } }; From 1deb164bfea8601d2e44a2dcf49b91ef6c281fdf Mon Sep 17 00:00:00 2001 From: Mikhail Pozdnyakov Date: Wed, 24 Jul 2019 13:18:40 +0300 Subject: [PATCH 2/4] [core] Default GeometryTileFeature::getGeometries() implementation --- src/mbgl/style/expression/expression.cpp | 3 --- src/mbgl/tile/geometry_tile_data.cpp | 5 +++++ src/mbgl/tile/geometry_tile_data.hpp | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/mbgl/style/expression/expression.cpp b/src/mbgl/style/expression/expression.cpp index 4800f6aa7f6..4c810431d0e 100644 --- a/src/mbgl/style/expression/expression.cpp +++ b/src/mbgl/style/expression/expression.cpp @@ -17,7 +17,6 @@ class GeoJSONFeature : public GeometryTileFeature { } PropertyMap getProperties() const override { return feature.properties; } FeatureIdentifier getID() const override { return feature.id; } - const GeometryCollection& getGeometries() const override { return geometry; } optional getValue(const std::string& key) const override { auto it = feature.properties.find(key); if (it != feature.properties.end()) { @@ -25,8 +24,6 @@ class GeoJSONFeature : public GeometryTileFeature { } return optional(); } - - GeometryCollection geometry; }; diff --git a/src/mbgl/tile/geometry_tile_data.cpp b/src/mbgl/tile/geometry_tile_data.cpp index 2dda9ecae4d..c7aea35944e 100644 --- a/src/mbgl/tile/geometry_tile_data.cpp +++ b/src/mbgl/tile/geometry_tile_data.cpp @@ -180,4 +180,9 @@ Feature convertFeature(const GeometryTileFeature& geometryTileFeature, const Can return feature; } +const GeometryCollection& GeometryTileFeature::getGeometries() const { + static const GeometryCollection dummy; + return dummy; +} + } // namespace mbgl diff --git a/src/mbgl/tile/geometry_tile_data.hpp b/src/mbgl/tile/geometry_tile_data.hpp index db3378a019d..a0d41608a3e 100644 --- a/src/mbgl/tile/geometry_tile_data.hpp +++ b/src/mbgl/tile/geometry_tile_data.hpp @@ -44,7 +44,7 @@ class GeometryTileFeature { virtual optional getValue(const std::string& key) const = 0; virtual PropertyMap getProperties() const { return PropertyMap(); } virtual FeatureIdentifier getID() const { return NullValue {}; } - virtual const GeometryCollection& getGeometries() const = 0; + virtual const GeometryCollection& getGeometries() const; }; class GeometryTileLayer { From ee248117a2f20277bc2b666ac55ac0a95315e086 Mon Sep 17 00:00:00 2001 From: Mikhail Pozdnyakov Date: Wed, 24 Jul 2019 14:12:04 +0300 Subject: [PATCH 3/4] [core] Optimize RenderLineLayer::queryIntersectsFeature --- .../renderer/layers/render_line_layer.cpp | 35 +++++++++++++------ 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/src/mbgl/renderer/layers/render_line_layer.cpp b/src/mbgl/renderer/layers/render_line_layer.cpp index 5c56826bd70..fcd52b21dfa 100644 --- a/src/mbgl/renderer/layers/render_line_layer.cpp +++ b/src/mbgl/renderer/layers/render_line_layer.cpp @@ -214,16 +214,22 @@ void RenderLineLayer::render(PaintParameters& parameters) { } } -optional offsetLine(const GeometryCollection& rings, const double offset) { - if (offset == 0) return {}; +namespace { + +GeometryCollection offsetLine(const GeometryCollection& rings, double offset) { + assert(offset != 0.0f); + assert(!rings.empty()); GeometryCollection newRings; - Point zero(0, 0); + newRings.reserve(rings.size()); + + const Point zero(0, 0); for (const auto& ring : rings) { newRings.emplace_back(); auto& newRing = newRings.back(); + newRing.reserve(ring.size()); - for (auto i = ring.begin(); i != ring.end(); i++) { + for (auto i = ring.begin(); i != ring.end(); ++i) { auto& p = *i; Point aToB = i == ring.begin() ? @@ -237,13 +243,15 @@ optional offsetLine(const GeometryCollection& rings, const d const double cosHalfAngle = extrude.x * bToC.x + extrude.y * bToC.y; extrude *= (1.0 / cosHalfAngle); - newRing.push_back(convertPoint(extrude * offset) + p); + newRing.emplace_back(convertPoint(extrude * offset) + p); } } return newRings; } +} // namespace + bool RenderLineLayer::queryIntersectsFeature( const GeometryCoordinates& queryGeometry, const GeometryTileFeature& feature, @@ -263,16 +271,21 @@ bool RenderLineLayer::queryIntersectsFeature( // Evaluate function auto offset = evaluated.get() .evaluate(feature, zoom, style::LineOffset::defaultValue()) * pixelsToTileUnits; + // Test intersection + const float halfWidth = getLineWidth(feature, zoom) / 2.0 * pixelsToTileUnits; // Apply offset to geometry - auto offsetGeometry = offsetLine(feature.getGeometries(), offset); + if (offset != 0.0f && !feature.getGeometries().empty()) { + return util::polygonIntersectsBufferedMultiLine( + translatedQueryGeometry.value_or(queryGeometry), + offsetLine(feature.getGeometries(), offset), + halfWidth); + } - // Test intersection - const float halfWidth = getLineWidth(feature, zoom) / 2.0 * pixelsToTileUnits; return util::polygonIntersectsBufferedMultiLine( - translatedQueryGeometry.value_or(queryGeometry), - offsetGeometry.value_or(feature.getGeometries()), - halfWidth); + translatedQueryGeometry.value_or(queryGeometry), + feature.getGeometries(), + halfWidth); } void RenderLineLayer::updateColorRamp() { From 4392194880f2db76010410f0c1b67afd22e97eb6 Mon Sep 17 00:00:00 2001 From: Mikhail Pozdnyakov Date: Wed, 24 Jul 2019 14:52:40 +0300 Subject: [PATCH 4/4] [core] GeometryCollection must not be implicitly copied --- src/mbgl/layout/pattern_layout.hpp | 2 +- src/mbgl/layout/symbol_feature.hpp | 2 +- src/mbgl/tile/geometry_tile_data.cpp | 23 +++++++------- src/mbgl/tile/geometry_tile_data.hpp | 7 ++++ src/mbgl/tile/geometry_tile_worker.cpp | 2 +- test/gl/bucket.test.cpp | 2 +- test/util/merge_lines.test.cpp | 44 +++++++++++++------------- 7 files changed, 44 insertions(+), 38 deletions(-) diff --git a/src/mbgl/layout/pattern_layout.hpp b/src/mbgl/layout/pattern_layout.hpp index 95f8b181fc9..858d5153472 100644 --- a/src/mbgl/layout/pattern_layout.hpp +++ b/src/mbgl/layout/pattern_layout.hpp @@ -106,7 +106,7 @@ class PatternLayout : public Layout { const auto i = patternFeature.i; std::unique_ptr feature = std::move(patternFeature.feature); const PatternLayerMap& patterns = patternFeature.patterns; - GeometryCollection geometries = feature->getGeometries(); + const GeometryCollection& geometries = feature->getGeometries(); bucket->addFeature(*feature, geometries, patternPositions, patterns); featureIndex->insert(geometries, i, sourceLayerID, bucketLeaderID); diff --git a/src/mbgl/layout/symbol_feature.hpp b/src/mbgl/layout/symbol_feature.hpp index 2c952fc12ac..72e88fb55e4 100644 --- a/src/mbgl/layout/symbol_feature.hpp +++ b/src/mbgl/layout/symbol_feature.hpp @@ -13,7 +13,7 @@ class SymbolFeature : public GeometryTileFeature { public: SymbolFeature(std::unique_ptr feature_) : feature(std::move(feature_)), - geometry(feature->getGeometries()) // we need a mutable copy of the geometry for mergeLines() + geometry(feature->getGeometries().clone()) // we need a mutable copy of the geometry for mergeLines() {} FeatureType getType() const override { return feature->getType(); } diff --git a/src/mbgl/tile/geometry_tile_data.cpp b/src/mbgl/tile/geometry_tile_data.cpp index c7aea35944e..db9f37ad4b8 100644 --- a/src/mbgl/tile/geometry_tile_data.cpp +++ b/src/mbgl/tile/geometry_tile_data.cpp @@ -57,32 +57,31 @@ std::vector classifyRings(const GeometryCollection& rings) { std::size_t len = rings.size(); if (len <= 1) { - polygons.push_back(rings); + polygons.emplace_back(rings.clone()); return polygons; } GeometryCollection polygon; int8_t ccw = 0; - for (std::size_t i = 0; i < len; i++) { - double area = signedArea(rings[i]); - - if (area == 0) - continue; + for (const auto& ring : rings) { + double area = signedArea(ring); + if (area == 0) continue; - if (ccw == 0) + if (ccw == 0) { ccw = (area < 0 ? -1 : 1); + } if (ccw == (area < 0 ? -1 : 1) && !polygon.empty()) { - polygons.push_back(polygon); - polygon.clear(); + polygons.emplace_back(std::move(polygon)); } - polygon.push_back(rings[i]); + polygon.emplace_back(ring); } - if (!polygon.empty()) - polygons.push_back(polygon); + if (!polygon.empty()) { + polygons.emplace_back(std::move(polygon)); + } return polygons; } diff --git a/src/mbgl/tile/geometry_tile_data.hpp b/src/mbgl/tile/geometry_tile_data.hpp index a0d41608a3e..203afcace7c 100644 --- a/src/mbgl/tile/geometry_tile_data.hpp +++ b/src/mbgl/tile/geometry_tile_data.hpp @@ -35,6 +35,13 @@ class GeometryCollection : public std::vector { GeometryCollection(Args&&... args) : std::vector(std::forward(args)...) {} GeometryCollection(std::initializer_list args) : std::vector(std::move(args)) {} + GeometryCollection(GeometryCollection&&) = default; + GeometryCollection& operator=(GeometryCollection&&) = default; + + GeometryCollection clone() const { return GeometryCollection(*this); } + +private: + GeometryCollection(const GeometryCollection&) = default; }; class GeometryTileFeature { diff --git a/src/mbgl/tile/geometry_tile_worker.cpp b/src/mbgl/tile/geometry_tile_worker.cpp index a69825d346b..f4d57e5bfc4 100644 --- a/src/mbgl/tile/geometry_tile_worker.cpp +++ b/src/mbgl/tile/geometry_tile_worker.cpp @@ -382,7 +382,7 @@ void GeometryTileWorker::parse() { if (!filter(expression::EvaluationContext { static_cast(this->id.overscaledZ), feature.get() })) continue; - GeometryCollection geometries = feature->getGeometries(); + const GeometryCollection& geometries = feature->getGeometries(); bucket->addFeature(*feature, geometries, {}, PatternLayerMap ()); featureIndex->insert(geometries, i, sourceLayerID, leaderImpl.id); } diff --git a/test/gl/bucket.test.cpp b/test/gl/bucket.test.cpp index 9c9847cf4db..f97fd539190 100644 --- a/test/gl/bucket.test.cpp +++ b/test/gl/bucket.test.cpp @@ -131,7 +131,7 @@ TEST(Buckets, SymbolBucket) { // SymbolBucket::addFeature() is a no-op. GeometryCollection point { { { 0, 0 } } }; - bucket.addFeature(StubGeometryTileFeature { {}, FeatureType::Point, point, properties }, point, {}, PatternLayerMap()); + bucket.addFeature(StubGeometryTileFeature { {}, FeatureType::Point, std::move(point), properties }, point, {}, PatternLayerMap()); ASSERT_FALSE(bucket.hasData()); ASSERT_FALSE(bucket.needsUpload()); diff --git a/test/util/merge_lines.test.cpp b/test/util/merge_lines.test.cpp index 1c8c7aae8f0..5dc846ad6e1 100644 --- a/test/util/merge_lines.test.cpp +++ b/test/util/merge_lines.test.cpp @@ -42,14 +42,14 @@ TEST(MergeLines, SameText) { input1.push_back(SymbolFeatureStub({}, FeatureType::LineString, {{{6, 0}, {7, 0}, {8, 0}}}, properties, aaa, {}, 0)); input1.push_back(SymbolFeatureStub({}, FeatureType::LineString, {{{5, 0}, {6, 0}}}, properties, aaa, {}, 0)); - const std::vector expected1 = { - { {}, FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}}}, properties }, - { {}, FeatureType::LineString, {{{4, 0}, {5, 0}, {6, 0}}}, properties }, - { {}, FeatureType::LineString, {{{5, 0}, {6, 0}, {7, 0}, {8, 0}, {9, 0}}}, properties }, - { {}, FeatureType::LineString, { emptyLine }, properties }, - { {}, FeatureType::LineString, { emptyLine }, properties }, - { {}, FeatureType::LineString, { emptyLine }, properties } - }; + std::vector expected1; + expected1.emplace_back(StubGeometryTileFeature({}, FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}}}, properties)); + expected1.emplace_back(StubGeometryTileFeature({}, FeatureType::LineString, {{{4, 0}, {5, 0}, {6, 0}}}, properties)); + expected1.emplace_back(StubGeometryTileFeature({}, FeatureType::LineString, {{{5, 0}, {6, 0}, {7, 0}, {8, 0}, {9, 0}}}, properties)); + expected1.emplace_back(StubGeometryTileFeature({}, FeatureType::LineString, { emptyLine }, properties)); + expected1.emplace_back(StubGeometryTileFeature({}, FeatureType::LineString, { emptyLine }, properties)); + expected1.emplace_back(StubGeometryTileFeature({}, FeatureType::LineString, { emptyLine }, properties)); + mbgl::util::mergeLines(input1); @@ -65,11 +65,11 @@ TEST(MergeLines, BothEnds) { input2.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {{{4, 0}, {5, 0}, {6, 0}}}, properties, aaa, {}, 0 }); input2.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {{{2, 0}, {3, 0}, {4, 0}}}, properties, aaa, {}, 0 }); - const std::vector expected2 = { - { {}, FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {6, 0}}}, properties }, - { {}, FeatureType::LineString, { emptyLine }, properties }, - { {}, FeatureType::LineString, { emptyLine }, properties } - }; + std::vector expected2; + expected2.emplace_back(StubGeometryTileFeature({}, FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {6, 0}}}, properties)); + expected2.emplace_back(StubGeometryTileFeature({}, FeatureType::LineString, { emptyLine }, properties)); + expected2.emplace_back(StubGeometryTileFeature({}, FeatureType::LineString, { emptyLine }, properties)); + mbgl::util::mergeLines(input2); @@ -85,11 +85,11 @@ TEST(MergeLines, CircularLines) { input3.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {{{2, 0}, {3, 0}, {4, 0}}}, properties, aaa, {}, 0 }); input3.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {{{4, 0}, {0, 0}}}, properties, aaa, {}, 0 }); - const std::vector expected3 = { - { {}, FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {0, 0}}}, properties }, - { {}, FeatureType::LineString, { emptyLine }, properties }, - { {}, FeatureType::LineString, { emptyLine }, properties } - }; + std::vector expected3; + expected3.emplace_back(StubGeometryTileFeature({}, FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {0, 0}}}, properties)); + expected3.emplace_back(StubGeometryTileFeature({}, FeatureType::LineString, { emptyLine }, properties)); + expected3.emplace_back(StubGeometryTileFeature({}, FeatureType::LineString, { emptyLine }, properties)); + mbgl::util::mergeLines(input3); @@ -102,20 +102,20 @@ TEST(MergeLines, EmptyOuterGeometry) { std::vector input; input.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {}, properties, aaa, {}, 0 }); - const std::vector expected = { { {}, FeatureType::LineString, {}, properties } }; + const StubGeometryTileFeature expected{ {}, FeatureType::LineString, {}, properties }; mbgl::util::mergeLines(input); - EXPECT_EQ(input[0].geometry, expected[0].getGeometries()); + EXPECT_EQ(input[0].geometry, expected.getGeometries()); } TEST(MergeLines, EmptyInnerGeometry) { std::vector input; input.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {}, properties, aaa, {}, 0 }); - const std::vector expected = { { {}, FeatureType::LineString, {}, properties } }; + const StubGeometryTileFeature expected{ {}, FeatureType::LineString, {}, properties }; mbgl::util::mergeLines(input); - EXPECT_EQ(input[0].geometry, expected[0].getGeometries()); + EXPECT_EQ(input[0].geometry, expected.getGeometries()); }