Custom Drawable Layer: Symbol Icon (#1908)

This commit is contained in:
Stefan Karschti
2024-02-16 17:39:47 +02:00
committed by GitHub
parent 612b256821
commit d6db72e8ba
32 changed files with 789 additions and 30 deletions

View File

@@ -14,11 +14,14 @@
#include <mbgl/style/layers/custom_drawable_layer.hpp>
#include <mbgl/util/constants.hpp>
#include <mbgl/util/logging.hpp>
#include <mbgl/util/image.hpp>
#include <mbgl/util/io.hpp>
#include <memory>
#include <cmath>
class TestDrawableLayer : public mbgl::style::CustomDrawableLayerHost {
class LineTestDrawableLayer : public mbgl::style::CustomDrawableLayerHost {
public:
void initialize() override {}
@@ -104,6 +107,24 @@ public:
}
}
// finish
interface.finish();
}
void deinitialize() override {}
};
class FillTestDrawableLayer : public mbgl::style::CustomDrawableLayerHost {
public:
void initialize() override {}
void update(Interface& interface) override {
// if we have built our drawable(s) already, either update or skip
if (interface.getDrawableCount()) return;
// set tile
interface.setTileID({11, 327, 791});
// add fill polygon
{
using namespace mbgl;
@@ -141,7 +162,65 @@ public:
void deinitialize() override {}
};
TEST(CustomDrawableLayer, Basic) {
class SymbolIconTestDrawableLayer : public mbgl::style::CustomDrawableLayerHost {
public:
void initialize() override {}
void update(Interface& interface) override {
// if we have built our drawable(s) already, either update or skip
if (interface.getDrawableCount()) return;
// set tile
interface.setTileID({11, 327, 791});
// add symbol icon
{
using namespace mbgl;
GeometryCoordinate position{static_cast<int16_t>(util::EXTENT * 0.5f),
static_cast<int16_t>(util::EXTENT * 0.5f)};
// load image
std::string imageData; // doh!
constexpr auto imagePath = "test/fixtures/custom_drawable_layer/symbol_icon/pin1.png";
try {
imageData = util::read_file(imagePath);
} catch (std::exception& ex) {
using namespace std::string_literals;
Log::Error(Event::Setup, "Failed to load expected image "s + imagePath + ": " + ex.what());
throw;
}
std::shared_ptr<PremultipliedImage> image = std::make_shared<PremultipliedImage>(decodeImage(imageData));
// set symbol options
Interface::SymbolOptions options;
options.texture = interface.context.createTexture2D();
options.texture->setImage(image);
options.texture->setSamplerConfiguration(
{gfx::TextureFilterType::Linear, gfx::TextureWrapType::Clamp, gfx::TextureWrapType::Clamp});
options.textureCoordinates = {{{0.0f, 0.08f}, {1.0f, 0.9f}}};
const float xspan = options.textureCoordinates[1][0] - options.textureCoordinates[0][0];
const float yspan = options.textureCoordinates[1][1] - options.textureCoordinates[0][1];
assert(xspan > 0.0f && yspan > 0.0f);
options.size = {static_cast<uint32_t>(image->size.width * 0.2f * xspan),
static_cast<uint32_t>(image->size.height * 0.2f * yspan)};
options.anchor = {0.5f, 0.95f};
options.angleDegrees = 45.0f;
options.scaleWithMap = false;
options.pitchWithMap = false;
interface.setSymbolOptions(options);
// add symbol
interface.addSymbol(position);
}
// finish
interface.finish();
}
void deinitialize() override {}
};
TEST(CustomDrawableLayer, Line) {
using namespace mbgl;
using namespace mbgl::style;
@@ -154,21 +233,63 @@ TEST(CustomDrawableLayer, Basic) {
ResourceOptions().withCachePath(":memory:").withAssetPath("test/fixtures/api/assets"));
// load style
map.getStyle().loadJSON(util::read_file("test/fixtures/api/water.json"));
map.getStyle().loadJSON(util::read_file("test/fixtures/api/simple.json"));
map.jumpTo(CameraOptions().withCenter(LatLng{37.8, -122.4426032}).withZoom(10.0));
// add fill layer
auto layer = std::make_unique<FillLayer>("landcover", "mapbox");
layer->setSourceLayer("landcover");
layer->setFillColor(Color{1.0, 1.0, 0.0, 1.0});
map.getStyle().addLayer(std::move(layer));
// add custom drawable layer
map.getStyle().addLayer(
std::make_unique<CustomDrawableLayer>("custom-drawable", std::make_unique<TestDrawableLayer>()));
std::make_unique<CustomDrawableLayer>("custom-drawable", std::make_unique<LineTestDrawableLayer>()));
// render and test
test::checkImage("test/fixtures/custom_drawable_layer/basic", frontend.render(map).image, 0.000657, 0.1);
test::checkImage("test/fixtures/custom_drawable_layer/line", frontend.render(map).image, 0.000657, 0.1);
}
TEST(CustomDrawableLayer, Fill) {
using namespace mbgl;
using namespace mbgl::style;
util::RunLoop loop;
HeadlessFrontend frontend{1};
Map map(frontend,
MapObserver::nullObserver(),
MapOptions().withMapMode(MapMode::Static).withSize(frontend.getSize()),
ResourceOptions().withCachePath(":memory:").withAssetPath("test/fixtures/api/assets"));
// load style
map.getStyle().loadJSON(util::read_file("test/fixtures/api/simple.json"));
map.jumpTo(CameraOptions().withCenter(LatLng{37.8, -122.4426032}).withZoom(10.0));
// add custom drawable layer
map.getStyle().addLayer(
std::make_unique<CustomDrawableLayer>("custom-drawable", std::make_unique<FillTestDrawableLayer>()));
// render and test
test::checkImage("test/fixtures/custom_drawable_layer/fill", frontend.render(map).image, 0.000657, 0.1);
}
TEST(CustomDrawableLayer, SymbolIcon) {
using namespace mbgl;
using namespace mbgl::style;
util::RunLoop loop;
HeadlessFrontend frontend{1};
Map map(frontend,
MapObserver::nullObserver(),
MapOptions().withMapMode(MapMode::Static).withSize(frontend.getSize()),
ResourceOptions().withCachePath(":memory:").withAssetPath("test/fixtures/api/assets"));
// load style
map.getStyle().loadJSON(util::read_file("test/fixtures/api/simple.json"));
map.jumpTo(CameraOptions().withCenter(LatLng{37.8, -122.4426032}).withZoom(10.0));
// add custom drawable layer
map.getStyle().addLayer(
std::make_unique<CustomDrawableLayer>("custom-drawable", std::make_unique<SymbolIconTestDrawableLayer>()));
// render and test
test::checkImage("test/fixtures/custom_drawable_layer/symbol_icon", frontend.render(map).image, 0.000657, 0.1);
}
#endif // MLN_DRAWABLE_RENDERER