Files
MapLibreParticleLab/src/mbgl/style/layer.cpp
Alexander Shalamov ffea0af9bf Add generic setter for 'source' property
- Add setter for 'source' property
- Test generic setters via setProperty method
2020-04-16 13:52:54 -04:00

230 lines
6.9 KiB
C++

#include <mbgl/style/conversion/constant.hpp>
#include <mbgl/style/conversion/filter.hpp>
#include <mbgl/style/conversion_impl.hpp>
#include <mbgl/style/layer.hpp>
#include <mbgl/style/layer_impl.hpp>
#include <mbgl/style/layer_observer.hpp>
#include <mbgl/tile/tile.hpp>
#include <mbgl/renderer/render_layer.hpp>
#include <mbgl/util/logging.hpp>
namespace mbgl {
namespace style {
static_assert(mbgl::underlying_type(Tile::Kind::Geometry) == mbgl::underlying_type(LayerTypeInfo::TileKind::Geometry),
"tile kind error");
static_assert(mbgl::underlying_type(Tile::Kind::Raster) == mbgl::underlying_type(LayerTypeInfo::TileKind::Raster),
"tile kind error");
static_assert(mbgl::underlying_type(Tile::Kind::RasterDEM) == mbgl::underlying_type(LayerTypeInfo::TileKind::RasterDEM),
"tile kind error");
static LayerObserver nullObserver;
Layer::Layer(Immutable<Impl> impl)
: baseImpl(std::move(impl)),
observer(&nullObserver) {
}
Layer::~Layer() = default;
std::string Layer::getID() const {
return baseImpl->id;
}
std::string Layer::getSourceID() const {
return baseImpl->source;
}
std::string Layer::getSourceLayer() const {
return baseImpl->sourceLayer;
}
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_);
observer->onLayerChanged(*this);
}
VisibilityType Layer::getVisibility() const {
return baseImpl->visibility;
}
void Layer::setVisibility(VisibilityType value) {
if (value == getVisibility())
return;
auto impl_ = mutableBaseImpl();
impl_->visibility = value;
baseImpl = std::move(impl_);
observer->onLayerChanged(*this);
}
float Layer::getMinZoom() const {
return baseImpl->minZoom;
}
float Layer::getMaxZoom() const {
return baseImpl->maxZoom;
}
void Layer::setMinZoom(float minZoom) {
if (getMinZoom() == minZoom) return;
auto impl_ = mutableBaseImpl();
impl_->minZoom = minZoom;
baseImpl = std::move(impl_);
observer->onLayerChanged(*this);
}
void Layer::setMaxZoom(float maxZoom) {
if (getMaxZoom() == maxZoom) return;
auto impl_ = mutableBaseImpl();
impl_->maxZoom = maxZoom;
baseImpl = std::move(impl_);
observer->onLayerChanged(*this);
}
Value Layer::serialize() const {
mapbox::base::ValueObject result;
result.emplace(std::make_pair("id", getID()));
result.emplace(std::make_pair("type", Layer::getTypeInfo()->type));
auto source = getSourceID();
if (!source.empty()) {
result.emplace(std::make_pair("source", std::move(source)));
}
auto sourceLayer = getSourceLayer();
if (!sourceLayer.empty()) {
result.emplace(std::make_pair("source-layer", std::move(sourceLayer)));
}
if (getFilter()) {
result.emplace(std::make_pair("filter", getFilter().serialize()));
}
if (getMinZoom() != -std::numeric_limits<float>::infinity()) {
result.emplace(std::make_pair("minzoom", getMinZoom()));
}
if (getMaxZoom() != std::numeric_limits<float>::infinity()) {
result.emplace(std::make_pair("maxzoom", getMaxZoom()));
}
if (getVisibility() == VisibilityType::None) {
result["layout"] = mapbox::base::ValueObject{std::make_pair("visibility", "none")};
}
return result;
}
void Layer::serializeProperty(Value& out, const StyleProperty& property, const char* propertyName, bool isPaint) const {
assert(out.getObject());
auto& object = *(out.getObject());
std::string propertyType = isPaint ? "paint" : "layout";
auto it = object.find(propertyType);
auto pair = std::make_pair(std::string(propertyName), Value{property.getValue()});
if (it != object.end()) {
assert(it->second.getObject());
it->second.getObject()->emplace(std::move(pair));
} else {
object[propertyType] = mapbox::base::ValueObject{{std::move(pair)}};
}
}
void Layer::setObserver(LayerObserver* observer_) {
observer = observer_ ? observer_ : &nullObserver;
}
optional<conversion::Error> Layer::setProperty(const std::string& name, const conversion::Convertible& value) {
using namespace conversion;
optional<Error> error = setPropertyInternal(name, value);
if (!error) return error; // Successfully set by the derived class implementation.
if (name == "visibility") return setVisibility(value);
if (name == "minzoom") {
if (auto zoom = convert<float>(value, *error)) {
setMinZoom(*zoom);
return nullopt;
}
} else if (name == "maxzoom") {
if (auto zoom = convert<float>(value, *error)) {
setMaxZoom(*zoom);
return nullopt;
}
} else if (name == "filter") {
if (auto filter = convert<Filter>(value, *error)) {
setFilter(*filter);
return nullopt;
}
} else if (name == "source-layer") {
if (auto sourceLayer = convert<std::string>(value, *error)) {
if (getTypeInfo()->source != LayerTypeInfo::Source::Required) {
Log::Warning(mbgl::Event::General,
"'source-layer' property cannot be set to"
"the layer %s",
baseImpl->id.c_str());
return nullopt;
}
setSourceLayer(*sourceLayer);
return nullopt;
}
} else if (name == "source") {
if (auto sourceID = convert<std::string>(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;
}
optional<conversion::Error> Layer::setVisibility(const conversion::Convertible& value) {
using namespace conversion;
if (isUndefined(value)) {
setVisibility(VisibilityType::Visible);
return nullopt;
}
Error error;
optional<VisibilityType> visibility = convert<VisibilityType>(value, error);
if (!visibility) {
return error;
}
setVisibility(*visibility);
return nullopt;
}
const LayerTypeInfo* Layer::getTypeInfo() const noexcept {
return baseImpl->getTypeInfo();
}
} // namespace style
} // namespace mbgl