summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorMolly Lloyd <mollymerp@users.noreply.github.com>2018-01-23 10:49:23 -0800
committerGitHub <noreply@github.com>2018-01-23 10:49:23 -0800
commitf3294200c6c866e5ab031ad8346c59a76aa37249 (patch)
tree6d9aedb552552607641a15c415a60be99a0877d5 /test
parent2d15aed43c9faa875a8f625c3afc286f1175e0ce (diff)
downloadqtlocation-mapboxgl-f3294200c6c866e5ab031ad8346c59a76aa37249.tar.gz
[core] add raster-dem source type and hillshade layer type (#10642)
Diffstat (limited to 'test')
-rw-r--r--test/geometry/dem_data.test.cpp140
-rw-r--r--test/style/source.test.cpp194
-rw-r--r--test/tile/raster_dem_tile.test.cpp93
3 files changed, 427 insertions, 0 deletions
diff --git a/test/geometry/dem_data.test.cpp b/test/geometry/dem_data.test.cpp
new file mode 100644
index 0000000000..30091973b2
--- /dev/null
+++ b/test/geometry/dem_data.test.cpp
@@ -0,0 +1,140 @@
+#include <mbgl/test/util.hpp>
+
+#include <mbgl/util/image.hpp>
+#include <mbgl/geometry/dem_data.hpp>
+
+using namespace mbgl;
+
+auto fakeImage = [](Size s) {
+ PremultipliedImage img = PremultipliedImage(s);
+
+ for (size_t i = 0; i < img.bytes(); i ++) {
+ img.data[i] = (i+1) % 4 == 0 ? 1 : std::rand() % 255;
+ }
+ return img;
+};
+
+TEST(DEMData, Constructor) {
+ PremultipliedImage image = fakeImage({16, 16});
+ DEMData pyramid(image);
+
+ EXPECT_EQ(pyramid.dim, 16);
+ EXPECT_EQ(pyramid.border, 8);
+ EXPECT_EQ(pyramid.stride, 32);
+ EXPECT_EQ(pyramid.getImage()->bytes(), size_t(32*32*4));
+ EXPECT_EQ(pyramid.dim, 16);
+ EXPECT_EQ(pyramid.border, 8);
+};
+
+TEST(DEMData, RoundTrip) {
+ PremultipliedImage image = fakeImage({16, 16});
+ DEMData pyramid(image);
+
+ pyramid.set(4, 6, 255);
+ EXPECT_EQ(pyramid.get(4, 6), 255);
+}
+
+TEST(DEMData, InitialBackfill) {
+
+ PremultipliedImage image1 = fakeImage({4, 4});
+ DEMData dem1(image1);
+
+ bool nonempty = true;
+ // checking that a 1 px border around the fake image has been populated
+ // with a non-empty pixel value
+ for (int x = -1; x < 5; x++){
+ for (int y = -1; y < 5; y ++) {
+ if (dem1.get(x, y) == -65536) {
+ nonempty = false;
+ break;
+ }
+ }
+ }
+ EXPECT_TRUE(nonempty);
+
+ bool verticalBorderMatch = true;
+ int vertx[] = {-1, 4};
+ for (int x : vertx) {
+ for (int y = 0; y < 4; y++) {
+ if (dem1.get(x, y) != dem1.get(x < 0 ? x + 1 : x - 1, y)) {
+ verticalBorderMatch = false;
+ break;
+ }
+ }
+ }
+ // vertical border of DEM data is initially equal to next column of data
+ EXPECT_TRUE(verticalBorderMatch);
+
+ // horizontal borders empty
+ bool horizontalBorderMatch = true;
+ int horiz[] = {-1, 4};
+ for (int y : horiz) {
+ for (int x = 0; x < 4; x++) {
+ if (dem1.get(x, y) != dem1.get(x, y < 0 ? y + 1 : y - 1)) {
+ horizontalBorderMatch = false;
+ break;
+ }
+ }
+ }
+ //horizontal border of DEM data is initially equal to next row of data
+
+ EXPECT_TRUE(horizontalBorderMatch);
+ // -1, 1 corner initially equal to closest corner data
+ EXPECT_TRUE(dem1.get(-1, 4) == dem1.get(0, 3));
+ // 1, 1 corner initially equal to closest corner data
+ EXPECT_TRUE(dem1.get(4, 4) == dem1.get(3, 3));
+ // -1, -1 corner initially equal to closest corner data
+ EXPECT_TRUE(dem1.get(-1, -1) == dem1.get(0, 0));
+ // -1, 1 corner initially equal to closest corner data
+ EXPECT_TRUE(dem1.get(4, -1) == dem1.get(3, 0));
+};
+
+TEST(DEMData, BackfillNeighbor) {
+ PremultipliedImage image1 = fakeImage({4, 4});
+ DEMData dem0(image1);
+
+ PremultipliedImage image2 = fakeImage({4, 4});
+ DEMData dem1(image2);
+
+ dem0.backfillBorder(dem1, -1, 0);
+ for (int y = 0; y < 4; y++) {
+ // dx = -1, dy = 0, so the left edge of dem1 should equal the right edge of dem0
+ // backfills Left neighbor
+ EXPECT_TRUE(dem0.get(-1, y) == dem1.get(3, y));
+
+ }
+
+ dem0.backfillBorder(dem1, 0, -1);
+ // backfills TopCenter neighbor
+ for (int x = 0; x < 4; x++) {
+ EXPECT_TRUE(dem0.get(x, -1) == dem1.get(x, 3));
+ }
+
+ dem0.backfillBorder(dem1, 1, 0);
+ // backfills Right neighbor
+ for (int y = 0; y < 4; y++) {
+ EXPECT_TRUE(dem0.get(4, y) == dem1.get(0, y));
+ }
+
+ dem0.backfillBorder(dem1, 0, 1);
+ // backfills BottomCenter neighbor
+ for (int x = 0; x < 4; x++) {
+ EXPECT_TRUE(dem0.get(x, 4) == dem1.get(x, 0));
+ }
+
+ dem0.backfillBorder(dem1, -1, 1);
+ // backfulls TopRight neighbor
+ EXPECT_TRUE(dem0.get(-1, 4) == dem1.get(3, 0));
+
+ dem0.backfillBorder(dem1, 1, 1);
+ // backfulls BottomRight neighbor
+ EXPECT_TRUE(dem0.get(4, 4) == dem1.get(0, 0));
+
+ dem0.backfillBorder(dem1, -1, -1);
+ // backfulls TopLeft neighbor
+ EXPECT_TRUE(dem0.get(-1, -1) == dem1.get(3, 3));
+
+ dem0.backfillBorder(dem1, 1, -1);
+ // backfulls BottomLeft neighbor
+ EXPECT_TRUE(dem0.get(4, -1) == dem1.get(0, 3));
+};
diff --git a/test/style/source.test.cpp b/test/style/source.test.cpp
index eb419e8080..6cb01146f6 100644
--- a/test/style/source.test.cpp
+++ b/test/style/source.test.cpp
@@ -6,14 +6,17 @@
#include <mbgl/style/style.hpp>
#include <mbgl/style/source_impl.hpp>
#include <mbgl/style/sources/raster_source.hpp>
+#include <mbgl/style/sources/raster_dem_source.hpp>
#include <mbgl/style/sources/vector_source.hpp>
#include <mbgl/style/sources/geojson_source.hpp>
#include <mbgl/style/sources/image_source.hpp>
#include <mbgl/style/sources/custom_geometry_source.hpp>
+#include <mbgl/style/layers/hillshade_layer.cpp>
#include <mbgl/style/layers/raster_layer.cpp>
#include <mbgl/style/layers/line_layer.hpp>
#include <mbgl/renderer/sources/render_raster_source.hpp>
+#include <mbgl/renderer/sources/render_raster_dem_source.hpp>
#include <mbgl/renderer/sources/render_vector_source.hpp>
#include <mbgl/renderer/sources/render_geojson_source.hpp>
#include <mbgl/renderer/tile_parameters.hpp>
@@ -173,6 +176,44 @@ TEST(Source, RasterTileEmpty) {
test.run();
}
+TEST(Source, RasterDEMTileEmpty) {
+ SourceTest test;
+
+ test.fileSource.tileResponse = [&] (const Resource&) {
+ Response response;
+ response.noContent = true;
+ return response;
+ };
+
+ HillshadeLayer layer("id", "source");
+ std::vector<Immutable<Layer::Impl>> layers {{ layer.baseImpl }};
+
+ Tileset tileset;
+ tileset.tiles = { "tiles" };
+
+ RasterDEMSource source("source", tileset, 512);
+ source.loadDescription(test.fileSource);
+
+ test.renderSourceObserver.tileChanged = [&] (RenderSource& source_, const OverscaledTileID&) {
+ EXPECT_EQ("source", source_.baseImpl->id);
+ test.end();
+ };
+
+ test.renderSourceObserver.tileError = [&] (RenderSource&, const OverscaledTileID&, std::exception_ptr) {
+ FAIL() << "Should never be called";
+ };
+
+ auto renderSource = RenderSource::create(source.baseImpl);
+ renderSource->setObserver(&test.renderSourceObserver);
+ renderSource->update(source.baseImpl,
+ layers,
+ true,
+ true,
+ test.tileParameters);
+
+ test.run();
+}
+
TEST(Source, VectorTileEmpty) {
SourceTest test;
@@ -251,6 +292,44 @@ TEST(Source, RasterTileFail) {
test.run();
}
+TEST(Source, RasterDEMTileFail) {
+ SourceTest test;
+
+ test.fileSource.tileResponse = [&] (const Resource&) {
+ Response response;
+ response.error = std::make_unique<Response::Error>(
+ Response::Error::Reason::Other,
+ "Failed by the test case");
+ return response;
+ };
+
+ HillshadeLayer layer("id", "source");
+ std::vector<Immutable<Layer::Impl>> layers {{ layer.baseImpl }};
+
+ Tileset tileset;
+ tileset.tiles = { "tiles" };
+
+ RasterDEMSource source("source", tileset, 512);
+ source.loadDescription(test.fileSource);
+
+ test.renderSourceObserver.tileError = [&] (RenderSource& source_, const OverscaledTileID& tileID, std::exception_ptr error) {
+ EXPECT_EQ(SourceType::RasterDEM, source_.baseImpl->type);
+ EXPECT_EQ(OverscaledTileID(0, 0, 0), tileID);
+ EXPECT_EQ("Failed by the test case", util::toString(error));
+ test.end();
+ };
+
+ auto renderSource = RenderSource::create(source.baseImpl);
+ renderSource->setObserver(&test.renderSourceObserver);
+ renderSource->update(source.baseImpl,
+ layers,
+ true,
+ true,
+ test.tileParameters);
+
+ test.run();
+}
+
TEST(Source, VectorTileFail) {
SourceTest test;
@@ -328,6 +407,43 @@ TEST(Source, RasterTileCorrupt) {
test.run();
}
+TEST(Source, RasterDEMTileCorrupt) {
+ SourceTest test;
+
+ test.fileSource.tileResponse = [&] (const Resource&) {
+ Response response;
+ response.data = std::make_unique<std::string>("CORRUPTED");
+ return response;
+ };
+
+ HillshadeLayer layer("id", "source");
+ std::vector<Immutable<Layer::Impl>> layers {{ layer.baseImpl }};
+
+ Tileset tileset;
+ tileset.tiles = { "tiles" };
+
+ RasterDEMSource source("source", tileset, 512);
+ source.loadDescription(test.fileSource);
+
+ test.renderSourceObserver.tileError = [&] (RenderSource& source_, const OverscaledTileID& tileID, std::exception_ptr error) {
+ EXPECT_EQ(source_.baseImpl->type, SourceType::RasterDEM);
+ EXPECT_EQ(OverscaledTileID(0, 0, 0), tileID);
+ EXPECT_TRUE(bool(error));
+ // Not asserting on platform-specific error text.
+ test.end();
+ };
+
+ auto renderSource = RenderSource::create(source.baseImpl);
+ renderSource->setObserver(&test.renderSourceObserver);
+ renderSource->update(source.baseImpl,
+ layers,
+ true,
+ true,
+ test.tileParameters);
+
+ test.run();
+}
+
TEST(Source, VectorTileCorrupt) {
SourceTest test;
@@ -402,6 +518,42 @@ TEST(Source, RasterTileCancel) {
test.run();
}
+TEST(Source, RasterDEMTileCancel) {
+ SourceTest test;
+
+ test.fileSource.tileResponse = [&] (const Resource&) {
+ test.end();
+ return optional<Response>();
+ };
+
+ HillshadeLayer layer("id", "source");
+ std::vector<Immutable<Layer::Impl>> layers {{ layer.baseImpl }};
+
+ Tileset tileset;
+ tileset.tiles = { "tiles" };
+
+ RasterDEMSource source("source", tileset, 512);
+ source.loadDescription(test.fileSource);
+
+ test.renderSourceObserver.tileChanged = [&] (RenderSource&, const OverscaledTileID&) {
+ FAIL() << "Should never be called";
+ };
+
+ test.renderSourceObserver.tileError = [&] (RenderSource&, const OverscaledTileID&, std::exception_ptr) {
+ FAIL() << "Should never be called";
+ };
+
+ auto renderSource = RenderSource::create(source.baseImpl);
+ renderSource->setObserver(&test.renderSourceObserver);
+ renderSource->update(source.baseImpl,
+ layers,
+ true,
+ true,
+ test.tileParameters);
+
+ test.run();
+}
+
TEST(Source, VectorTileCancel) {
SourceTest test;
@@ -484,6 +636,48 @@ TEST(Source, RasterTileAttribution) {
test.run();
}
+TEST(Source, RasterDEMTileAttribution) {
+ SourceTest test;
+
+ HillshadeLayer layer("id", "source");
+ std::vector<Immutable<Layer::Impl>> layers {{ layer.baseImpl }};
+
+ std::string mapbox = ("<a href='https://www.mapbox.com/about/maps/' target='_blank'>&copy; Mapbox</a> ");
+
+ test.fileSource.tileResponse = [&] (const Resource&) {
+ Response response;
+ response.noContent = true;
+ return response;
+ };
+
+ test.fileSource.sourceResponse = [&] (const Resource& resource) {
+ EXPECT_EQ("url", resource.url);
+ Response response;
+ response.data = std::make_unique<std::string>(R"TILEJSON({ "tilejson": "2.1.0", "attribution": ")TILEJSON" +
+ mapbox +
+ R"TILEJSON(", "tiles": [ "tiles" ] })TILEJSON");
+ return response;
+ };
+
+ test.styleObserver.sourceChanged = [&] (Source& source) {
+ EXPECT_EQ(mapbox, source.getAttribution());
+ test.end();
+ };
+
+ RasterDEMSource source("source", "url", 512);
+ source.setObserver(&test.styleObserver);
+ source.loadDescription(test.fileSource);
+
+ auto renderSource = RenderSource::create(source.baseImpl);
+ renderSource->update(source.baseImpl,
+ layers,
+ true,
+ true,
+ test.tileParameters);
+
+ test.run();
+}
+
TEST(Source, GeoJSonSourceUrlUpdate) {
SourceTest test;
diff --git a/test/tile/raster_dem_tile.test.cpp b/test/tile/raster_dem_tile.test.cpp
new file mode 100644
index 0000000000..c6f9b80b42
--- /dev/null
+++ b/test/tile/raster_dem_tile.test.cpp
@@ -0,0 +1,93 @@
+#include <mbgl/test/util.hpp>
+#include <mbgl/test/fake_file_source.hpp>
+#include <mbgl/tile/raster_dem_tile.hpp>
+#include <mbgl/tile/tile_loader_impl.hpp>
+
+#include <mbgl/style/style.hpp>
+#include <mbgl/util/default_thread_pool.hpp>
+#include <mbgl/util/run_loop.hpp>
+#include <mbgl/map/transform.hpp>
+#include <mbgl/annotation/annotation_manager.hpp>
+#include <mbgl/renderer/tile_parameters.hpp>
+#include <mbgl/renderer/buckets/hillshade_bucket.hpp>
+#include <mbgl/renderer/image_manager.hpp>
+#include <mbgl/text/glyph_manager.hpp>
+
+using namespace mbgl;
+
+class RasterDEMTileTest {
+public:
+ FakeFileSource fileSource;
+ TransformState transformState;
+ util::RunLoop loop;
+ ThreadPool threadPool { 1 };
+ style::Style style { loop, fileSource, 1 };
+ AnnotationManager annotationManager { style };
+ ImageManager imageManager;
+ GlyphManager glyphManager { fileSource };
+ Tileset tileset { { "https://example.com" }, { 0, 22 }, "none" };
+
+ TileParameters tileParameters {
+ 1.0,
+ MapDebugOptions(),
+ transformState,
+ threadPool,
+ fileSource,
+ MapMode::Continuous,
+ annotationManager,
+ imageManager,
+ glyphManager,
+ 0
+ };
+};
+
+TEST(RasterDEMTile, setError) {
+ RasterDEMTileTest test;
+ RasterDEMTile tile(OverscaledTileID(0, 0, 0), test.tileParameters, test.tileset);
+ tile.setError(std::make_exception_ptr(std::runtime_error("test")));
+ EXPECT_FALSE(tile.isRenderable());
+ EXPECT_TRUE(tile.isLoaded());
+ EXPECT_TRUE(tile.isComplete());
+}
+
+TEST(RasterDEMTile, onError) {
+ RasterDEMTileTest test;
+ RasterDEMTile tile(OverscaledTileID(0, 0, 0), test.tileParameters, test.tileset);
+ tile.onError(std::make_exception_ptr(std::runtime_error("test")), 0);
+ EXPECT_FALSE(tile.isRenderable());
+ EXPECT_TRUE(tile.isLoaded());
+ EXPECT_TRUE(tile.isComplete());
+}
+
+TEST(RasterDEMTile, onParsed) {
+ RasterDEMTileTest test;
+ RasterDEMTile tile(OverscaledTileID(0, 0, 0), test.tileParameters, test.tileset);
+ tile.onParsed(std::make_unique<HillshadeBucket>(PremultipliedImage({16, 16})), 0);
+ EXPECT_TRUE(tile.isRenderable());
+ EXPECT_TRUE(tile.isLoaded());
+ EXPECT_TRUE(tile.isComplete());
+
+ // Make sure that once we've had a renderable tile and then receive erroneous data, we retain
+ // the previously rendered data and keep the tile renderable.
+ tile.setError(std::make_exception_ptr(std::runtime_error("Connection offline")));
+ EXPECT_TRUE(tile.isRenderable());
+ EXPECT_TRUE(tile.isLoaded());
+ EXPECT_TRUE(tile.isComplete());
+
+ // Then simulate a parsing failure and make sure that we keep it renderable in this situation
+ // as well.
+ tile.onError(std::make_exception_ptr(std::runtime_error("Parse error")), 0);
+ ASSERT_TRUE(tile.isRenderable());
+ EXPECT_TRUE(tile.isLoaded());
+ EXPECT_TRUE(tile.isComplete());
+}
+
+TEST(RasterDEMTile, onParsedEmpty) {
+ RasterDEMTileTest test;
+ RasterDEMTile tile(OverscaledTileID(0, 0, 0), test.tileParameters, test.tileset);
+ tile.onParsed(nullptr, 0);
+ EXPECT_FALSE(tile.isRenderable());
+ EXPECT_TRUE(tile.isLoaded());
+ EXPECT_TRUE(tile.isComplete());
+}
+