[core] Add batch conversion of latLngs to/from screenCoords (#15891)
* [core] Add batch conversion of latLng vs screenCoord * [core] Take the simple approach
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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>);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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));
|
||||
|
||||
LatLng tl = test.map.latLngForPixel(ScreenCoordinate(0, 0));
|
||||
LatLng br = test.map.latLngForPixel(ScreenCoordinate(viewSize.width, viewSize.height));
|
||||
// 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());
|
||||
|
||||
std::vector<LatLng> latLngs = {
|
||||
tl,
|
||||
test.map.latLngForPixel(ScreenCoordinate(viewSize.width, 0)),
|
||||
test.map.latLngForPixel(ScreenCoordinate(0, viewSize.height)),
|
||||
br,
|
||||
center};
|
||||
// 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);
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user