diff options
author | zmiao <miao.zhao@mapbox.com> | 2019-11-07 18:16:31 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-11-07 18:16:31 +0200 |
commit | 2e8a350d68be75d9505fab9dc897c4abbcae05aa (patch) | |
tree | e73bd5c629b3357326e663a8405c35c227b36ff2 | |
parent | 1d49c23b8558e8c24a51e7ba84525ddd06f231be (diff) | |
download | qtlocation-mapboxgl-2e8a350d68be75d9505fab9dc897c4abbcae05aa.tar.gz |
[core] Add batch conversion of latLngs to/from screenCoords (#15891)
* [core] Add batch conversion of latLng vs screenCoord
* [core] Take the simple approach
-rw-r--r-- | benchmark/api/query.benchmark.cpp | 27 | ||||
-rw-r--r-- | include/mbgl/map/map.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/map/map.cpp | 18 | ||||
-rw-r--r-- | test/api/annotations.test.cpp | 49 | ||||
-rw-r--r-- | test/api/query.test.cpp | 16 |
5 files changed, 99 insertions, 13 deletions
diff --git a/benchmark/api/query.benchmark.cpp b/benchmark/api/query.benchmark.cpp index 5e7fd823e0..12a28b95e7 100644 --- a/benchmark/api/query.benchmark.cpp +++ b/benchmark/api/query.benchmark.cpp @@ -38,6 +38,30 @@ public: } // end namespace +static void API_queryPixelsForLatLngs(::benchmark::State& state) { + std::vector<LatLng> points; + int count = 10000; + for (int i = 0; i < count; ++i) { + points.emplace_back(1, 1); + } + QueryBenchmark bench; + while (state.KeepRunning()) { + (void)bench.map.pixelsForLatLngs(points); + } +} + +static void API_queryLatLngsForPixels(::benchmark::State& state) { + std::vector<ScreenCoordinate> points; + int count = 10000; + for (int i = 0; i < count; ++i) { + points.emplace_back(1, 1); + } + QueryBenchmark bench; + while (state.KeepRunning()) { + (void)bench.map.latLngsForPixels(points); + } +} + static void API_queryRenderedFeaturesAll(::benchmark::State& state) { QueryBenchmark bench; @@ -61,7 +85,8 @@ static void API_queryRenderedFeaturesLayerFromHighDensity(::benchmark::State& st bench.frontend.getRenderer()->queryRenderedFeatures(bench.box, {{{"road-street" }}, {}}); } } - +BENCHMARK(API_queryPixelsForLatLngs); +BENCHMARK(API_queryLatLngsForPixels); BENCHMARK(API_queryRenderedFeaturesAll); BENCHMARK(API_queryRenderedFeaturesLayerFromLowDensity); BENCHMARK(API_queryRenderedFeaturesLayerFromHighDensity); diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp index ac0a398d25..4757bb398c 100644 --- a/include/mbgl/map/map.hpp +++ b/include/mbgl/map/map.hpp @@ -97,6 +97,8 @@ public: // Projection ScreenCoordinate pixelForLatLng(const LatLng&) const; LatLng latLngForPixel(const ScreenCoordinate&) const; + std::vector<ScreenCoordinate> pixelsForLatLngs(const std::vector<LatLng>&) const; + std::vector<LatLng> latLngsForPixels(const std::vector<ScreenCoordinate>&) const; // Annotations void addAnnotationImage(std::unique_ptr<style::Image>); diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index 649e0e321e..3ea2fc43c6 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -364,6 +364,24 @@ LatLng Map::latLngForPixel(const ScreenCoordinate& pixel) const { return impl->transform.screenCoordinateToLatLng(pixel); } +std::vector<ScreenCoordinate> Map::pixelsForLatLngs(const std::vector<LatLng>& latLngs) const { + std::vector<ScreenCoordinate> ret; + ret.reserve(latLngs.size()); + for (const auto& latLng : latLngs) { + ret.emplace_back(pixelForLatLng(latLng)); + } + return ret; +} + +std::vector<LatLng> Map::latLngsForPixels(const std::vector<ScreenCoordinate>& screenCoords) const { + std::vector<LatLng> ret; + ret.reserve(screenCoords.size()); + for (const auto& point : screenCoords) { + ret.emplace_back(latLngForPixel(point)); + } + return ret; +} + #pragma mark - Annotations void Map::addAnnotationImage(std::unique_ptr<style::Image> image) { diff --git a/test/api/annotations.test.cpp b/test/api/annotations.test.cpp index 4886d90a93..bedf7a208d 100644 --- a/test/api/annotations.test.cpp +++ b/test/api/annotations.test.cpp @@ -354,12 +354,24 @@ TEST(Annotations, QueryRenderedFeatures) { test.frontend.render(test.map); - auto features = test.frontend.getRenderer()->queryRenderedFeatures(test.map.pixelForLatLng({ 0, 0 })); + // Batch conversion of latLngs to pixels + auto points = test.map.pixelsForLatLngs({{0, 0}, {50, 0}}); + ASSERT_EQ(2, points.size()); + // Single conversion of latLng to pixel + auto point0 = test.map.pixelForLatLng({0, 0}); + ASSERT_NEAR(points[0].x, point0.x, 1e-8); + ASSERT_NEAR(points[0].y, point0.y, 1e-8); + + auto point1 = test.map.pixelForLatLng({50, 0}); + ASSERT_NEAR(points[1].x, point1.x, 1e-8); + ASSERT_NEAR(points[1].y, point1.y, 1e-8); + + auto features = test.frontend.getRenderer()->queryRenderedFeatures(point0); EXPECT_EQ(features.size(), 1u); EXPECT_EQ(features[0].id.is<NullValue>(), false); EXPECT_EQ(features[0].id, uint64_t(0)); - auto features2 = test.frontend.getRenderer()->queryRenderedFeatures(test.map.pixelForLatLng({ 50, 0 })); + auto features2 = test.frontend.getRenderer()->queryRenderedFeatures(point1); EXPECT_EQ(features2.size(), 1u); EXPECT_EQ(features[0].id.is<NullValue>(), false); EXPECT_EQ(features2[0].id, uint64_t(1)); @@ -452,19 +464,37 @@ TEST(Annotations, ViewFrustumCulling) { const LatLng center = { 5.0, 5.0 }; test.map.jumpTo(CameraOptions().withCenter(center).withZoom(3.0)); + // Batch conversion of pixels to latLngs + const std::vector<LatLng> batchLatLngs = + test.map.latLngsForPixels({ScreenCoordinate(0, 0), + ScreenCoordinate(viewSize.width, viewSize.height), + ScreenCoordinate(viewSize.width, 0), + ScreenCoordinate(0, viewSize.height)}); + ASSERT_EQ(4, batchLatLngs.size()); + + // Single conversion of pixel to latLng LatLng tl = test.map.latLngForPixel(ScreenCoordinate(0, 0)); + ASSERT_NEAR(batchLatLngs[0].latitude(), tl.latitude(), 1e-8); + ASSERT_NEAR(batchLatLngs[0].longitude(), tl.longitude(), 1e-8); + LatLng br = test.map.latLngForPixel(ScreenCoordinate(viewSize.width, viewSize.height)); + ASSERT_NEAR(batchLatLngs[1].latitude(), br.latitude(), 1e-8); + ASSERT_NEAR(batchLatLngs[1].longitude(), br.longitude(), 1e-8); + + LatLng bl = test.map.latLngForPixel(ScreenCoordinate(viewSize.width, 0)); + ASSERT_NEAR(batchLatLngs[2].latitude(), bl.latitude(), 1e-8); + ASSERT_NEAR(batchLatLngs[2].longitude(), bl.longitude(), 1e-8); - std::vector<LatLng> latLngs = { - tl, - test.map.latLngForPixel(ScreenCoordinate(viewSize.width, 0)), - test.map.latLngForPixel(ScreenCoordinate(0, viewSize.height)), - br, - center}; + LatLng tr = test.map.latLngForPixel(ScreenCoordinate(0, viewSize.height)); + ASSERT_NEAR(batchLatLngs[3].latitude(), tr.latitude(), 1e-8); + ASSERT_NEAR(batchLatLngs[3].longitude(), tr.longitude(), 1e-8); + + std::vector<LatLng> latLngs = {tl, bl, tr, br, center}; std::vector<mbgl::AnnotationID> ids; for (auto latLng : latLngs) { - ids.push_back(test.map.addAnnotation(SymbolAnnotation { { latLng.longitude(), latLng.latitude() }, "default_marker" })); + ids.push_back( + test.map.addAnnotation(SymbolAnnotation{{latLng.longitude(), latLng.latitude()}, "default_marker"})); } std::vector<std::pair<CameraOptions, std::vector<uint64_t>>> expectedVisibleForCamera = { @@ -550,4 +580,3 @@ TEST(Annotations, ChangeMaxZoom) { test.map.jumpTo(CameraOptions().withZoom(*test.map.getBounds().maxZoom)); test.checkRendering("line_annotation_max_zoom"); } - diff --git a/test/api/query.test.cpp b/test/api/query.test.cpp index 83aeec81ec..54ae89767a 100644 --- a/test/api/query.test.cpp +++ b/test/api/query.test.cpp @@ -75,10 +75,22 @@ std::vector<Feature> getTopClusterFeature(QueryTest& test) { TEST(Query, QueryRenderedFeatures) { QueryTest test; - auto features1 = test.frontend.getRenderer()->queryRenderedFeatures(test.map.pixelForLatLng({ 0, 0 })); + // Batch conversion of latLngs to pixels + auto points = test.map.pixelsForLatLngs({{0, 0}, {9, 9}}); + ASSERT_EQ(2, points.size()); + // Single conversion of latLng to pixel + auto point0 = test.map.pixelForLatLng({0, 0}); + ASSERT_NEAR(points[0].x, point0.x, 1e-8); + ASSERT_NEAR(points[0].y, point0.y, 1e-8); + + auto point1 = test.map.pixelForLatLng({9, 9}); + ASSERT_NEAR(points[1].x, point1.x, 1e-8); + ASSERT_NEAR(points[1].y, point1.y, 1e-8); + + auto features1 = test.frontend.getRenderer()->queryRenderedFeatures(point0); EXPECT_EQ(features1.size(), 4u); - auto features2 = test.frontend.getRenderer()->queryRenderedFeatures(test.map.pixelForLatLng({ 9, 9 })); + auto features2 = test.frontend.getRenderer()->queryRenderedFeatures(point1); EXPECT_EQ(features2.size(), 0u); } |