#pragma once #include #include #include #include #include #include #include #include #include #include #include #include namespace mbgl { namespace style { namespace conversion { template optional setLayoutProperty(Layer& layer, const std::string& name, const V& value) { static const auto setters = makeLayoutPropertySetters(); auto it = setters.find(name); if (it == setters.end()) { return Error { "property not found" }; } return it->second(layer, value); } template optional setPaintProperty(Layer& layer, const std::string& name, const V& value) { static const auto setters = makePaintPropertySetters(); auto it = setters.find(name); if (it == setters.end()) { return Error { "property not found" }; } return it->second(layer, value); } template optional setPaintProperties(Layer& layer, const V& value) { auto paintValue = objectMember(value, "paint"); if (!paintValue) { return {}; } return eachMember(*paintValue, [&] (const std::string& k, const V& v) { return setPaintProperty(layer, k, v); }); } template <> struct Converter> { public: template optional> operator()(const V& value, Error& error) const { if (!isObject(value)) { error = { "layer must be an object" }; return {}; } auto idValue = objectMember(value, "id"); if (!idValue) { error = { "layer must have an id" }; return {}; } optional id = toString(*idValue); if (!id) { error = { "layer id must be a string" }; return {}; } auto typeValue = objectMember(value, "type"); if (!typeValue) { error = { "layer must have a type" }; return {}; } optional type = toString(*typeValue); if (!type) { error = { "layer type must be a string" }; return {}; } optional> converted; if (*type == "fill") { converted = convertVectorLayer(*id, value, error); } else if (*type == "fill-extrusion") { converted = convertVectorLayer(*id, value, error); } else if (*type == "line") { converted = convertVectorLayer(*id, value, error); } else if (*type == "circle") { converted = convertVectorLayer(*id, value, error); } else if (*type == "symbol") { converted = convertVectorLayer(*id, value, error); } else if (*type == "raster") { converted = convertRasterLayer(*id, value, error); } else if (*type == "background") { converted = convertBackgroundLayer(*id, value, error); } else { error = { "invalid layer type" }; return {}; } if (!converted) { return converted; } std::unique_ptr layer = std::move(*converted); auto minzoomValue = objectMember(value, "minzoom"); if (minzoomValue) { optional minzoom = toNumber(*minzoomValue); if (!minzoom) { error = { "minzoom must be numeric" }; return {}; } layer->setMinZoom(*minzoom); } auto maxzoomValue = objectMember(value, "maxzoom"); if (maxzoomValue) { optional maxzoom = toNumber(*maxzoomValue); if (!maxzoom) { error = { "maxzoom must be numeric" }; return {}; } layer->setMaxZoom(*maxzoom); } auto layoutValue = objectMember(value, "layout"); if (layoutValue) { if (!isObject(*layoutValue)) { error = { "layout must be an object" }; return {}; } optional error_ = eachMember(*layoutValue, [&] (const std::string& k, const V& v) { return setLayoutProperty(*layer, k, v); }); if (error_) { error = *error_; return {}; } } optional error_ = setPaintProperties(*layer, value); if (error_) { error = *error_; return {}; } return std::move(layer); } private: template optional> convertVectorLayer(const std::string& id, const V& value, Error& error) const { auto sourceValue = objectMember(value, "source"); if (!sourceValue) { error = { "layer must have a source" }; return {}; } optional source = toString(*sourceValue); if (!source) { error = { "layer source must be a string" }; return {}; } std::unique_ptr layer = std::make_unique(id, *source); auto sourceLayerValue = objectMember(value, "source-layer"); if (sourceLayerValue) { optional sourceLayer = toString(*sourceLayerValue); if (!sourceLayer) { error = { "layer source-layer must be a string" }; return {}; } layer->setSourceLayer(*sourceLayer); } auto filterValue = objectMember(value, "filter"); if (filterValue) { optional filter = convert(*filterValue, error); if (!filter) { return {}; } layer->setFilter(*filter); } return { std::move(layer) }; } template optional> convertRasterLayer(const std::string& id, const V& value, Error& error) const { auto sourceValue = objectMember(value, "source"); if (!sourceValue) { error = { "layer must have a source" }; return {}; } optional source = toString(*sourceValue); if (!source) { error = { "layer source must be a string" }; return {}; } return { std::make_unique(id, *source) }; } template optional> convertBackgroundLayer(const std::string& id, const V&, Error&) const { return { std::make_unique(id) }; } }; } // namespace conversion } // namespace style } // namespace mbgl