diff --git a/include/mbgl/style/layer.hpp b/include/mbgl/style/layer.hpp index 53e0f0f18ed..9884ad0a357 100644 --- a/include/mbgl/style/layer.hpp +++ b/include/mbgl/style/layer.hpp @@ -94,6 +94,7 @@ class Layer { std::string getSourceID() const; std::string getSourceLayer() const; void setSourceLayer(const std::string& sourceLayer); + void setSourceID(const std::string& sourceID); // Filter const Filter& getFilter() const; diff --git a/src/mbgl/style/layer.cpp b/src/mbgl/style/layer.cpp index d6a855fd64b..428bcc9a5ad 100644 --- a/src/mbgl/style/layer.cpp +++ b/src/mbgl/style/layer.cpp @@ -41,16 +41,25 @@ std::string Layer::getSourceLayer() const { } void Layer::setSourceLayer(const std::string& sourceLayer) { + if (getSourceLayer() == sourceLayer) return; auto impl_ = mutableBaseImpl(); impl_->sourceLayer = sourceLayer; baseImpl = std::move(impl_); } +void Layer::setSourceID(const std::string& sourceID) { + if (getSourceID() == sourceID) return; + auto impl_ = mutableBaseImpl(); + impl_->source = sourceID; + baseImpl = std::move(impl_); +}; + const Filter& Layer::getFilter() const { return baseImpl->filter; } void Layer::setFilter(const Filter& filter) { + if (getFilter() == filter) return; auto impl_ = mutableBaseImpl(); impl_->filter = filter; baseImpl = std::move(impl_); @@ -79,6 +88,7 @@ float Layer::getMaxZoom() const { } void Layer::setMinZoom(float minZoom) { + if (getMinZoom() == minZoom) return; auto impl_ = mutableBaseImpl(); impl_->minZoom = minZoom; baseImpl = std::move(impl_); @@ -86,6 +96,7 @@ void Layer::setMinZoom(float minZoom) { } void Layer::setMaxZoom(float maxZoom) { + if (getMaxZoom() == maxZoom) return; auto impl_ = mutableBaseImpl(); impl_->maxZoom = maxZoom; baseImpl = std::move(impl_); @@ -168,7 +179,7 @@ optional Layer::setProperty(const std::string& name, const co if (auto sourceLayer = convert(value, *error)) { if (getTypeInfo()->source != LayerTypeInfo::Source::Required) { Log::Warning(mbgl::Event::General, - "source-layer property cannot be applied to" + "'source-layer' property cannot be set to" "the layer %s", baseImpl->id.c_str()); return nullopt; @@ -176,6 +187,18 @@ optional Layer::setProperty(const std::string& name, const co setSourceLayer(*sourceLayer); return nullopt; } + } else if (name == "source") { + if (auto sourceID = convert(value, *error)) { + if (getTypeInfo()->source != LayerTypeInfo::Source::Required) { + Log::Warning(mbgl::Event::General, + "'source' property cannot be set to" + "the layer %s", + baseImpl->id.c_str()); + return nullopt; + } + setSourceID(*sourceID); + return nullopt; + } } return error; } diff --git a/test/style/conversion/layer.test.cpp b/test/style/conversion/layer.test.cpp index 742f9021682..079d7ce5a5f 100644 --- a/test/style/conversion/layer.test.cpp +++ b/test/style/conversion/layer.test.cpp @@ -148,4 +148,20 @@ TEST(StyleConversion, SetGenericProperties) { EXPECT_EQ(12.0f, layer->getMinZoom()); EXPECT_EQ(18.0f, layer->getMaxZoom()); EXPECT_EQ("landmarks", layer->getSourceLayer()); + + const JSValue newComposite("composite_2"); + layer->setProperty("source", Convertible(&newComposite)); + EXPECT_EQ("composite_2", layer->getSourceID()); + + const JSValue newSourceLayer("poi"); + layer->setProperty("source-layer", Convertible(&newSourceLayer)); + EXPECT_EQ("poi", layer->getSourceLayer()); + + const JSValue newMinZoom(1.0f); + layer->setProperty("minzoom", Convertible(&newMinZoom)); + EXPECT_EQ(1.0f, layer->getMinZoom()); + + const JSValue newMaxZoom(22.0f); + layer->setProperty("maxzoom", Convertible(&newMaxZoom)); + EXPECT_EQ(22.0f, layer->getMaxZoom()); } \ No newline at end of file diff --git a/test/style/style_layer.test.cpp b/test/style/style_layer.test.cpp index 33573636d7b..84bad2830b1 100644 --- a/test/style/style_layer.test.cpp +++ b/test/style/style_layer.test.cpp @@ -1,5 +1,7 @@ #include #include +#include +#include #include #include #include @@ -28,6 +30,7 @@ using namespace mbgl; using namespace mbgl::style; +using namespace mbgl::style::conversion; using namespace expression; using namespace expression::dsl; using namespace std::literals::string_literals; @@ -60,6 +63,11 @@ class MockLayoutProperties : public Properties {}; class MockPaintProperties : public Properties {}; using MockOverrides = FormatSectionOverrides; +mbgl::style::Filter parseFilter(const std::string& expression) { + Error error; + return *convertJSON(expression, error); +} + } // namespace TEST(Layer, BackgroundProperties) { @@ -221,7 +229,7 @@ TEST(Layer, Observer) { EXPECT_EQ(layer.get(), &layer_); filterChanged = true; }; - layer->setFilter(Filter()); + layer->setFilter(parseFilter(R"(["==", "foo", "bar"])")); EXPECT_TRUE(filterChanged); // Notifies observer on visibility change.