Merge branch 'master' of github.com:mapnik/mapnik
This commit is contained in:
commit
f3b864541c
17 changed files with 305 additions and 7 deletions
|
@ -412,6 +412,22 @@ void export_map()
|
|||
">>> m.background_image = '/path/to/image.png'\n"
|
||||
)
|
||||
|
||||
.add_property("background_image_comp_op",&Map::background_image_comp_op,
|
||||
&Map::set_background_image_comp_op,
|
||||
"The background image compositing operation.\n"
|
||||
"\n"
|
||||
"Usage:\n"
|
||||
">>> m.background_image_comp_op = mapnik.CompositeOp.src_over\n"
|
||||
)
|
||||
|
||||
.add_property("background_image_opacity",&Map::background_image_opacity,
|
||||
&Map::set_background_image_opacity,
|
||||
"The background image opacity.\n"
|
||||
"\n"
|
||||
"Usage:\n"
|
||||
">>> m.background_image_opacity = 1.0\n"
|
||||
)
|
||||
|
||||
.add_property("base",
|
||||
make_function(&Map::base_path,return_value_policy<copy_const_reference>()),
|
||||
&Map::set_base_path,
|
||||
|
|
|
@ -25,15 +25,17 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/color.hpp>
|
||||
#include <mapnik/config.hpp>
|
||||
#include <mapnik/font_set.hpp>
|
||||
#include <mapnik/enumeration.hpp>
|
||||
#include <mapnik/datasource.hpp> // for featureset_ptr
|
||||
#include <mapnik/layer.hpp>
|
||||
#include <mapnik/params.hpp>
|
||||
#include <mapnik/well_known_srs.hpp>
|
||||
#include <mapnik/image_compositing.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/optional/optional.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
@ -76,6 +78,8 @@ private:
|
|||
int buffer_size_;
|
||||
boost::optional<color> background_;
|
||||
boost::optional<std::string> background_image_;
|
||||
composite_mode_e background_image_comp_op_;
|
||||
float background_image_opacity_;
|
||||
std::map<std::string,feature_type_style> styles_;
|
||||
std::map<std::string,font_set> fontsets_;
|
||||
std::vector<layer> layers_;
|
||||
|
@ -286,10 +290,30 @@ public:
|
|||
*/
|
||||
boost::optional<std::string> const& background_image() const;
|
||||
|
||||
/*! \brief Set the compositing operation uses to blend the background image into the background color.
|
||||
* @param comp_op compositing operation.
|
||||
*/
|
||||
void set_background_image_comp_op(composite_mode_e comp_op);
|
||||
|
||||
/*! \brief Get the map background image compositing operation
|
||||
* @return Background image compositing operation as composite_mode_e
|
||||
* object
|
||||
*/
|
||||
composite_mode_e background_image_comp_op() const;
|
||||
|
||||
/*! \brief Set the map background image opacity.
|
||||
* @param opacity Background image opacity.
|
||||
*/
|
||||
void set_background_image_opacity(float opacity);
|
||||
|
||||
/*! \brief Get the map background image opacity
|
||||
* @return opacity value as float
|
||||
*/
|
||||
float background_image_opacity() const;
|
||||
|
||||
/*! \brief Set buffer size
|
||||
* @param buffer_size Buffer size in pixels.
|
||||
*/
|
||||
|
||||
void set_buffer_size(int buffer_size);
|
||||
|
||||
/*! \brief Get the map buffer size
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include <mapnik/simplify.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
// stl
|
||||
#include <vector>
|
||||
|
|
|
@ -162,13 +162,13 @@ void agg_renderer<T>::setup(Map const &m)
|
|||
if ( w > 0 && h > 0)
|
||||
{
|
||||
// repeat background-image both vertically and horizontally
|
||||
unsigned x_steps = unsigned(std::ceil(width_/double(w)));
|
||||
unsigned y_steps = unsigned(std::ceil(height_/double(h)));
|
||||
unsigned x_steps = static_cast<unsigned>(std::ceil(width_/double(w)));
|
||||
unsigned y_steps = static_cast<unsigned>(std::ceil(height_/double(h)));
|
||||
for (unsigned x=0;x<x_steps;++x)
|
||||
{
|
||||
for (unsigned y=0;y<y_steps;++y)
|
||||
{
|
||||
composite(pixmap_.data(),*bg_image, src_over, 1.0f, x*w, y*h, false);
|
||||
composite(pixmap_.data(),*bg_image, m.background_image_comp_op(), m.background_image_opacity(), x*w, y*h, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,6 +87,8 @@ namespace mapnik { namespace util {
|
|||
{
|
||||
map_out.set_background_image(*background_image);
|
||||
}
|
||||
map_out.set_background_image_comp_op(map_in.background_image_comp_op());
|
||||
map_out.set_background_image_opacity(map_in.background_image_opacity());
|
||||
// maximum extent
|
||||
boost::optional<box2d<double> > max_extent = map_in.maximum_extent();
|
||||
if (max_extent)
|
||||
|
|
|
@ -199,6 +199,26 @@ void map_parser::parse_map(Map & map, xml_node const& pt, std::string const& bas
|
|||
map.set_background_image(ensure_relative_to_xml(image_filename));
|
||||
}
|
||||
|
||||
optional<std::string> comp_op_name = map_node.get_opt_attr<std::string>("background-image-comp-op");
|
||||
if (comp_op_name)
|
||||
{
|
||||
optional<composite_mode_e> comp_op = comp_op_from_string(*comp_op_name);
|
||||
if (comp_op)
|
||||
{
|
||||
map.set_background_image_comp_op(*comp_op);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw config_error("failed to parse background-image-comp-op: '" + *comp_op_name + "'");
|
||||
}
|
||||
}
|
||||
|
||||
optional<float> opacity = map_node.get_opt_attr<float>("background-image-opacity");
|
||||
if (opacity)
|
||||
{
|
||||
map.set_background_image_opacity(*opacity);
|
||||
}
|
||||
|
||||
std::string srs = map_node.get_attr("srs", map.srs());
|
||||
try
|
||||
{
|
||||
|
|
28
src/map.cpp
28
src/map.cpp
|
@ -67,6 +67,8 @@ Map::Map()
|
|||
height_(400),
|
||||
srs_(MAPNIK_LONGLAT_PROJ),
|
||||
buffer_size_(0),
|
||||
background_image_comp_op_(src_over),
|
||||
background_image_opacity_(1.0),
|
||||
aspectFixMode_(GROW_BBOX),
|
||||
base_path_("") {}
|
||||
|
||||
|
@ -75,6 +77,8 @@ Map::Map(int width,int height, std::string const& srs)
|
|||
height_(height),
|
||||
srs_(srs),
|
||||
buffer_size_(0),
|
||||
background_image_comp_op_(src_over),
|
||||
background_image_opacity_(1.0),
|
||||
aspectFixMode_(GROW_BBOX),
|
||||
base_path_("") {}
|
||||
|
||||
|
@ -85,6 +89,8 @@ Map::Map(Map const& rhs)
|
|||
buffer_size_(rhs.buffer_size_),
|
||||
background_(rhs.background_),
|
||||
background_image_(rhs.background_image_),
|
||||
background_image_comp_op_(rhs.background_image_comp_op_),
|
||||
background_image_opacity_(rhs.background_image_opacity_),
|
||||
styles_(rhs.styles_),
|
||||
fontsets_(rhs.fontsets_),
|
||||
layers_(rhs.layers_),
|
||||
|
@ -105,6 +111,8 @@ Map& Map::operator=(Map const& rhs)
|
|||
buffer_size_ = rhs.buffer_size_;
|
||||
background_=rhs.background_;
|
||||
background_image_=rhs.background_image_;
|
||||
background_image_comp_op_=rhs.background_image_comp_op_;
|
||||
background_image_opacity_=rhs.background_image_opacity_;
|
||||
styles_=rhs.styles_;
|
||||
fontsets_ = rhs.fontsets_;
|
||||
layers_=rhs.layers_;
|
||||
|
@ -320,6 +328,26 @@ void Map::set_background_image(std::string const& image_filename)
|
|||
background_image_ = image_filename;
|
||||
}
|
||||
|
||||
composite_mode_e Map::background_image_comp_op() const
|
||||
{
|
||||
return background_image_comp_op_;
|
||||
}
|
||||
|
||||
void Map::set_background_image_comp_op(composite_mode_e comp_op)
|
||||
{
|
||||
background_image_comp_op_ = comp_op;
|
||||
}
|
||||
|
||||
float Map::background_image_opacity() const
|
||||
{
|
||||
return background_image_opacity_;
|
||||
}
|
||||
|
||||
void Map::set_background_image_opacity(float opacity)
|
||||
{
|
||||
background_image_opacity_ = opacity;
|
||||
}
|
||||
|
||||
void Map::set_maximum_extent(box2d<double> const& box)
|
||||
{
|
||||
maximum_extent_.reset(box);
|
||||
|
|
|
@ -831,6 +831,19 @@ void serialize_map(ptree & pt, Map const & map, bool explicit_defaults)
|
|||
set_attr( map_node, "background-image", *image_filename );
|
||||
}
|
||||
|
||||
composite_mode_e comp_op = map.background_image_comp_op();
|
||||
if (comp_op != src_over || explicit_defaults)
|
||||
{
|
||||
set_attr(map_node, "background-image-comp-op", *comp_op_to_string(comp_op));
|
||||
}
|
||||
|
||||
double opacity = map.background_image_opacity();
|
||||
if (opacity != 1.0 || explicit_defaults)
|
||||
{
|
||||
set_attr(map_node, "background-image-opacity", opacity);
|
||||
}
|
||||
|
||||
|
||||
int buffer_size = map.buffer_size();
|
||||
if ( buffer_size || explicit_defaults)
|
||||
{
|
||||
|
|
|
@ -336,6 +336,9 @@ def test_map_init():
|
|||
eq_(m.srs, '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs')
|
||||
eq_(m.base, '')
|
||||
eq_(m.maximum_extent, None)
|
||||
eq_(m.background_image, None)
|
||||
eq_(m.background_image_comp_op, mapnik.CompositeOp.src_over)
|
||||
eq_(m.background_image_opacity, 1.0)
|
||||
|
||||
m = mapnik.Map(256, 256, '+proj=latlong')
|
||||
eq_(m.srs, '+proj=latlong')
|
||||
|
|
BIN
tests/visual_tests/data/pattern.png
Normal file
BIN
tests/visual_tests/data/pattern.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
|
@ -0,0 +1,137 @@
|
|||
{
|
||||
"keys": [
|
||||
"",
|
||||
"1"
|
||||
],
|
||||
"data": {},
|
||||
"grid": [
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" !!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!!!!!!!!! ",
|
||||
" !!!!!!!!!!!!!!!! ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "
|
||||
]
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 80 KiB |
Binary file not shown.
After Width: | Height: | Size: 85 KiB |
Binary file not shown.
After Width: | Height: | Size: 102 KiB |
Binary file not shown.
After Width: | Height: | Size: 110 KiB |
|
@ -0,0 +1,54 @@
|
|||
<Map srs="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"
|
||||
background-color="green"
|
||||
background-image-opacity=".8"
|
||||
background-image-comp-op="screen"
|
||||
background-image="../data/pattern.png">
|
||||
|
||||
<Style name="ellipse">
|
||||
<Rule>
|
||||
<MarkersSymbolizer
|
||||
width="240"
|
||||
height="240"
|
||||
fill="steelblue"
|
||||
fill-opacity=".2"
|
||||
stroke="yellow"
|
||||
stroke-width="16"
|
||||
stroke-opacity=".3"
|
||||
/>
|
||||
</Rule>
|
||||
</Style>
|
||||
|
||||
<Layer name="layer" srs="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs">
|
||||
<StyleName>ellipse</StyleName>
|
||||
<Datasource>
|
||||
<Parameter name="type">csv</Parameter>
|
||||
<Parameter name="inline">
|
||||
x,y
|
||||
2.5,2.5
|
||||
</Parameter>
|
||||
</Datasource>
|
||||
</Layer>
|
||||
|
||||
<!-- points to frame data view -->
|
||||
|
||||
<Style name="frame">
|
||||
<Rule>
|
||||
<PointSymbolizer />
|
||||
</Rule>
|
||||
</Style>
|
||||
|
||||
<Layer name="frame" srs="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs">
|
||||
<StyleName>frame</StyleName>
|
||||
<Datasource>
|
||||
<Parameter name="type">csv</Parameter>
|
||||
<Parameter name="inline">
|
||||
x,y
|
||||
0,0
|
||||
5,0
|
||||
0,5
|
||||
5,5
|
||||
</Parameter>
|
||||
</Datasource>
|
||||
</Layer>
|
||||
|
||||
</Map>
|
|
@ -169,7 +169,8 @@ files = {
|
|||
'style-level-compositing-tiled-1,0':{'sizes':[(512,512)],'bbox':merc_z1_bboxes['1,0']},
|
||||
'style-level-compositing-tiled-0,1':{'sizes':[(512,512)],'bbox':merc_z1_bboxes['0,1']},
|
||||
'style-level-compositing-tiled-1,1':{'sizes':[(512,512)],'bbox':merc_z1_bboxes['1,1']},
|
||||
'marker-path-expression':{}
|
||||
'marker-path-expression':{},
|
||||
'map-background-image-compositing':{'sizes':[(512,512)]}
|
||||
}
|
||||
|
||||
class Reporting:
|
||||
|
|
Loading…
Reference in a new issue