summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/api/annotations.test.cpp67
-rw-r--r--test/fixtures/local_glyphs/no_local_with_content_insets/expected.pngbin0 -> 8428 bytes
-rw-r--r--test/fixtures/local_glyphs/no_local_with_content_insets_and_pitch/expected.pngbin0 -> 7263 bytes
-rw-r--r--test/map/transform.test.cpp45
-rw-r--r--test/text/local_glyph_rasterizer.test.cpp50
5 files changed, 148 insertions, 14 deletions
diff --git a/test/api/annotations.test.cpp b/test/api/annotations.test.cpp
index d7cb572cb0..03330dc4c6 100644
--- a/test/api/annotations.test.cpp
+++ b/test/api/annotations.test.cpp
@@ -434,6 +434,73 @@ TEST(Annotations, VisibleFeatures) {
EXPECT_EQ(features.size(), ids.size());
}
+TEST(Annotations, ViewFrustumCulling) {
+ // The purpose of the test is to control that annotations outside screen
+ // rectangle are not rendered for different camera setup, especially when
+ // using edge insets - viewport center is then offsetted.
+
+ // Important premise of this test is "static const float viewportPadding = 100;"
+ // as defined in collision_index.cpp: tests using edge insets are writen so that
+ // padding is 128 (half of viewSize width). If increasing viewportPadding,
+ // increase the padding in test cases below.
+ AnnotationTest test;
+
+ auto viewSize = test.frontend.getSize();
+ auto box = ScreenBox { {}, { double(viewSize.width), double(viewSize.height) } };
+
+ test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json"));
+ test.map.addAnnotationImage(namedMarker("default_marker"));
+ 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));
+
+ std::vector<LatLng> latLngs = {
+ tl,
+ test.map.latLngForPixel(ScreenCoordinate(viewSize.width, 0)),
+ test.map.latLngForPixel(ScreenCoordinate(0, viewSize.height)),
+ br,
+ center};
+
+ std::vector<mbgl::AnnotationID> ids;
+ for (auto latLng : latLngs) {
+ ids.push_back(test.map.addAnnotation(SymbolAnnotation { { latLng.longitude(), latLng.latitude() }, "default_marker" }));
+ }
+
+ std::vector<std::pair<CameraOptions, std::vector<uint64_t>>> expectedVisibleForCamera = {
+ // Start with all markers visible.
+ { CameraOptions(), { 0, 1, 2, 3, 4 } },
+ // Move center to topLeft: only former center and top left (now center) are visible.
+ { CameraOptions().withCenter(tl), { 0, 4 } },
+ // Reset center. With pitch: only top row markers and center are visible.
+ { CameraOptions().withCenter(center).withPitch(45), { 0, 1, 4 } },
+ // Reset pitch, and use padding to move viewport center: only topleft and center are visible.
+ { CameraOptions().withPitch(0).withPadding(EdgeInsets { viewSize.height * 0.5, viewSize.width * 0.5, 0, 0 }), { 0, 4 } },
+ // Use opposite padding to move viewport center: only bottom right and center are visible.
+ { CameraOptions().withPitch(0).withPadding(EdgeInsets { 0, 0, viewSize.height * 0.5, viewSize.width * 0.5 }), { 3, 4 } },
+ // Use top padding to move viewport center: top row and center are visible.
+ { CameraOptions().withPitch(0).withPadding(EdgeInsets { viewSize.height * 0.5, 0, 0, 0 }), { 0, 1, 4 } },
+ // Use bottom padding: only bottom right and center are visible.
+ { CameraOptions().withPitch(0).withPadding(EdgeInsets { 0, 0, viewSize.height * 0.5, 0 }), { 2, 3, 4 } },
+ // Left padding and pitch: top left, bottom left and center are visible.
+ { CameraOptions().withPitch(45).withPadding(EdgeInsets { 0, viewSize.width * 0.5, 0, 0 }), { 0, 2, 4 } }
+ };
+
+ for (unsigned i = 0; i < expectedVisibleForCamera.size(); i++) {
+ auto testCase = expectedVisibleForCamera[i];
+ test.map.jumpTo(testCase.first);
+ test.frontend.render(test.map);
+ auto features = test.frontend.getRenderer()->queryRenderedFeatures(box, {});
+ for (uint64_t id : testCase.second) { // testCase.second is vector of ids expected.
+ EXPECT_NE(std::find_if(features.begin(), features.end(), [&id](auto feature) {
+ return id == feature.id.template get<uint64_t>();
+ }), features.end()) << "Point with id " << id << " is missing in test case " << i;
+ EXPECT_EQ(features.size(), testCase.second.size()) << " in test case " << i;
+ }
+ }
+}
+
TEST(Annotations, TopOffsetPixels) {
AnnotationTest test;
diff --git a/test/fixtures/local_glyphs/no_local_with_content_insets/expected.png b/test/fixtures/local_glyphs/no_local_with_content_insets/expected.png
new file mode 100644
index 0000000000..f161a95c8e
--- /dev/null
+++ b/test/fixtures/local_glyphs/no_local_with_content_insets/expected.png
Binary files differ
diff --git a/test/fixtures/local_glyphs/no_local_with_content_insets_and_pitch/expected.png b/test/fixtures/local_glyphs/no_local_with_content_insets_and_pitch/expected.png
new file mode 100644
index 0000000000..edb8d07a40
--- /dev/null
+++ b/test/fixtures/local_glyphs/no_local_with_content_insets_and_pitch/expected.png
Binary files differ
diff --git a/test/map/transform.test.cpp b/test/map/transform.test.cpp
index 33d325dfb2..3d37312b17 100644
--- a/test/map/transform.test.cpp
+++ b/test/map/transform.test.cpp
@@ -288,25 +288,48 @@ TEST(Transform, Padding) {
ASSERT_DOUBLE_EQ(0, transform.getLatLng().latitude());
ASSERT_DOUBLE_EQ(0, transform.getLatLng().longitude());
-
- transform.jumpTo(CameraOptions().withCenter(LatLng { 10, -100 }).withZoom(10.0));
+ CameraOptions nonPaddedCameraOptions = CameraOptions().withCenter(LatLng { 10, -100 }).withZoom(10.0);
+ transform.jumpTo(nonPaddedCameraOptions);
const LatLng trueCenter = transform.getLatLng();
ASSERT_DOUBLE_EQ(10, trueCenter.latitude());
ASSERT_DOUBLE_EQ(-100, trueCenter.longitude());
ASSERT_DOUBLE_EQ(10, transform.getZoom());
- const LatLng manualShiftedCenter = transform.getState().screenCoordinateToLatLng({
+ const LatLng screenCenter = transform.screenCoordinateToLatLng({
+ 1000.0 / 2.0,
1000.0 / 2.0,
- 1000.0 / 4.0,
+ });
+ const LatLng upperHalfCenter = transform.screenCoordinateToLatLng({
+ 1000.0 / 2.0,
+ 1000.0 * 0.25,
});
EdgeInsets padding(1000.0 / 2.0, 0, 0, 0);
- const LatLng shiftedCenter = transform.getLatLng(padding);
- ASSERT_NE(trueCenter.latitude(), shiftedCenter.latitude());
- ASSERT_NEAR(trueCenter.longitude(), shiftedCenter.longitude(), 1e-8);
- ASSERT_DOUBLE_EQ(manualShiftedCenter.latitude(), shiftedCenter.latitude());
- ASSERT_DOUBLE_EQ(manualShiftedCenter.longitude(), shiftedCenter.longitude());
+ // CameraOption center and zoom don't change when padding changes: center of
+ // viewport remains the same as padding defines viwport center offset in rendering.
+ CameraOptions paddedOptions = CameraOptions().withPadding(padding);
+ transform.jumpTo(paddedOptions);
+ const LatLng theSameCenter = transform.getLatLng();
+ ASSERT_DOUBLE_EQ(trueCenter.latitude(), theSameCenter.latitude());
+ ASSERT_DOUBLE_EQ(trueCenter.longitude(), theSameCenter.longitude());
+
+ // However, LatLng is now at the center of lower half - verify conversion
+ // from screen coordinate to LatLng.
+ const LatLng paddedLowerHalfScreenCenter = transform.screenCoordinateToLatLng({
+ 1000.0 / 2.0,
+ 1000.0 * 0.75,
+ });
+ ASSERT_NEAR(screenCenter.latitude(), paddedLowerHalfScreenCenter.latitude(), 1e-10);
+ ASSERT_NEAR(screenCenter.longitude(), paddedLowerHalfScreenCenter.longitude(), 1e-10);
+
+ // LatLng previously in upper half center, should now be under screen center.
+ const LatLng paddedScreenCenter = transform.screenCoordinateToLatLng({
+ 1000.0 / 2.0,
+ 1000.0 / 2.0,
+ });
+ ASSERT_NEAR(upperHalfCenter.latitude(), paddedScreenCenter.latitude(), 1e-10);
+ ASSERT_NEAR(upperHalfCenter.longitude(), paddedScreenCenter.longitude(), 1e-10);
}
TEST(Transform, MoveBy) {
@@ -440,7 +463,7 @@ TEST(Transform, Camera) {
flyOptions.transitionFrameFn = [&](double t) {
ASSERT_TRUE(t >= 0 && t <= 1);
ASSERT_LE(latLng2.latitude(), transform.getLatLng().latitude());
- ASSERT_GE(latLng2.longitude(), transform.getLatLng({}, LatLng::Unwrapped).longitude());
+ ASSERT_GE(latLng2.longitude(), transform.getLatLng(LatLng::Unwrapped).longitude());
};
flyOptions.transitionFinishFn = [&]() {
// XXX Fix precision loss in flyTo:
@@ -618,7 +641,7 @@ TEST(Transform, LatLngBounds) {
// Try crossing the antimeridian from the right.
transform.jumpTo(CameraOptions().withCenter(LatLng { 0.0, 200.0 }));
- ASSERT_DOUBLE_EQ(transform.getLatLng({}, LatLng::Unwrapped).longitude(), 180.0);
+ ASSERT_DOUBLE_EQ(transform.getLatLng(LatLng::Unwrapped).longitude(), 180.0);
ASSERT_DOUBLE_EQ(transform.getLatLng().longitude(), -180.0);
// -1 | 0 | +1
diff --git a/test/text/local_glyph_rasterizer.test.cpp b/test/text/local_glyph_rasterizer.test.cpp
index ec8a728e9f..86dc87b6c7 100644
--- a/test/text/local_glyph_rasterizer.test.cpp
+++ b/test/text/local_glyph_rasterizer.test.cpp
@@ -43,9 +43,9 @@ public:
MapAdapter map { frontend, MapObserver::nullObserver(), fileSource,
MapOptions().withMapMode(MapMode::Static).withSize(frontend.getSize())};
- void checkRendering(const char * name) {
+ void checkRendering(const char * name, double imageMatchPixelsThreshold = 0.05, double pixelMatchThreshold = 0.1) {
test::checkImage(std::string("test/fixtures/local_glyphs/") + name,
- frontend.render(map), 0.05, 0.1);
+ frontend.render(map), imageMatchPixelsThreshold, pixelMatchThreshold);
}
};
@@ -85,6 +85,50 @@ TEST(LocalGlyphRasterizer, NoLocal) {
return response;
};
test.map.getStyle().loadJSON(util::read_file("test/fixtures/local_glyphs/mixed.json"));
- test.checkRendering("no_local");
+ test.checkRendering("no_local", 0.001, 0.1);
}
+TEST(LocalGlyphRasterizer, NoLocalWithContentInsets) {
+ // Expectations: content insets imply rendering to offsetted viewport center.
+ // Rendered text should be on the same offset and keep the same size as
+ // with no offset.
+ LocalGlyphRasterizerTest test({});
+
+ test.fileSource->glyphsResponse = [&] (const Resource& resource) {
+ EXPECT_EQ(Resource::Kind::Glyphs, resource.kind);
+ Response response;
+ response.data = std::make_shared<std::string>(util::read_file("test/fixtures/resources/glyphs.pbf"));
+ return response;
+ };
+ auto viewSize = test.frontend.getSize();
+ test.map.getStyle().loadJSON(util::read_file("test/fixtures/local_glyphs/mixed.json"));
+
+ // Expected image was created using center offset as in the line below - content insets,
+ // with no pitch defined, should produce the same output.
+ // test.map.moveBy({ viewSize.width * 0.25, 0 });
+
+ test.map.jumpTo(CameraOptions().withPadding(EdgeInsets { 0, viewSize.width * 0.25 * 2, 0, 0 }));
+ test.checkRendering("no_local_with_content_insets", 0.001, 0.1);
+}
+
+TEST(LocalGlyphRasterizer, NoLocalWithContentInsetsAndPitch) {
+ // Expectations: content insets imply rendering to offsetted viewport center.
+ // Rendered text should be on the same offset and keep the same size as
+ // with no offset.
+ LocalGlyphRasterizerTest test({});
+
+ test.fileSource->glyphsResponse = [&] (const Resource& resource) {
+ EXPECT_EQ(Resource::Kind::Glyphs, resource.kind);
+ Response response;
+ response.data = std::make_shared<std::string>(util::read_file("test/fixtures/resources/glyphs.pbf"));
+ return response;
+ };
+ auto viewSize = test.frontend.getSize();
+ test.map.getStyle().loadJSON(util::read_file("test/fixtures/local_glyphs/mixed.json"));
+
+ // Expected image was verified using no-padding render, offsetted to right
+ // using bitmap editor.
+
+ test.map.jumpTo(CameraOptions().withPitch(45).withPadding(EdgeInsets { 0, viewSize.width * 0.4, 0, 0 }));
+ test.checkRendering("no_local_with_content_insets_and_pitch", 0.001, 0.1);
+}