summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzmiao <miao.zhao@mapbox.com>2019-11-07 18:16:31 +0200
committerGitHub <noreply@github.com>2019-11-07 18:16:31 +0200
commit2e8a350d68be75d9505fab9dc897c4abbcae05aa (patch)
treee73bd5c629b3357326e663a8405c35c227b36ff2
parent1d49c23b8558e8c24a51e7ba84525ddd06f231be (diff)
downloadqtlocation-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.cpp27
-rw-r--r--include/mbgl/map/map.hpp2
-rw-r--r--src/mbgl/map/map.cpp18
-rw-r--r--test/api/annotations.test.cpp49
-rw-r--r--test/api/query.test.cpp16
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);
}