visual test: allow specifying image size with margins

the syntax is:

    margin_left '+' width_inner '+' margin_right,
    margin_top '+' height_inner '+' margin_bottom

for example:

    3+200+7, 4+100+6

will render image with width=210, height=110, but Map
extent (given or estimated) fitted to 200x100 pixels
This commit is contained in:
Mickey Rose 2018-08-07 19:52:52 +02:00
parent 2929c4ae6d
commit c836e80107
3 changed files with 72 additions and 13 deletions

View file

@ -43,6 +43,36 @@ struct map_size
map_size() { } map_size() { }
std::size_t width = 0; std::size_t width = 0;
std::size_t height = 0; std::size_t height = 0;
std::size_t margin_left = 0;
std::size_t margin_right = 0;
std::size_t margin_top = 0;
std::size_t margin_bottom = 0;
bool has_margin() const
{
return 0 != (margin_left | margin_right | margin_top | margin_bottom);
}
void inflate_by_margin(mapnik::box2d<double> & box) const
{
std::size_t xm = margin_left + margin_right;
if (xm > 0 && xm < width)
{
double pixel_width = box.width() / (width - xm);
box.minx_ -= pixel_width * margin_left;
box.maxx_ += pixel_width * margin_right;
}
std::size_t ym = margin_top + margin_bottom;
if (ym > 0 && ym < height)
{
double pixel_height = box.height() / (height - ym);
// FIXME this will swap top/bottom margins
// if map coordinate system has `y` growing in
// the same direction as screen coordinates
box.maxy_ += pixel_height * margin_top;
box.miny_ -= pixel_height * margin_bottom;
}
}
}; };
struct config struct config

View file

@ -25,20 +25,44 @@
#pragma GCC diagnostic push #pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp> #include <mapnik/warning_ignore.hpp>
#include <boost/spirit/home/x3.hpp> #include <boost/spirit/home/x3.hpp>
#include <boost/fusion/include/adapt_struct.hpp> #include <boost/fusion/include/at_c.hpp>
#include <boost/fusion/include/deque.hpp>
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
BOOST_FUSION_ADAPT_STRUCT (
visual_tests::map_size,
(std::size_t, width)
(std::size_t, height)
)
namespace visual_tests { namespace visual_tests {
namespace x3 = boost::spirit::x3; namespace x3 = boost::spirit::x3;
namespace fusion = boost::fusion;
using x3::attr;
using x3::ulong_; using x3::ulong_;
auto const map_size_rule = x3::rule<class map_size_rule, map_size> {} = ulong_ >> ',' >> ulong_;
using map_dimspec = fusion::deque<std::size_t, std::size_t, std::size_t>;
auto const map_dimspec_rule = x3::rule<class map_dimspec_rule, map_dimspec>{}
= ulong_ >> '+' >> ulong_ >> '+' >> ulong_
| attr(0UL) >> ulong_ >> attr(0UL)
;
auto const map_size_rule = x3::rule<class map_size_rule, map_size> {}
= map_dimspec_rule[(
[](auto & ctx) {
auto & v = _val(ctx);
auto a1 = fusion::at_c<1>(_attr(ctx));
v.margin_left = fusion::at_c<0>(_attr(ctx));
v.margin_right = fusion::at_c<2>(_attr(ctx));
v.width = v.margin_left + a1 + v.margin_right;
})]
>> ','
>> map_dimspec_rule[(
[](auto & ctx) {
auto & v = _val(ctx);
auto a1 = fusion::at_c<1>(_attr(ctx));
v.margin_top = fusion::at_c<0>(_attr(ctx));
v.margin_bottom = fusion::at_c<2>(_attr(ctx));
v.height = v.margin_top + a1 + v.margin_bottom;
})]
;
auto const map_sizes_grammar = x3::rule<class map_sizes_grammar_type, std::vector<map_size> > {} = auto const map_sizes_grammar = x3::rule<class map_sizes_grammar_type, std::vector<map_size> > {} =
map_size_rule % ';' ; map_size_rule % ';' ;

View file

@ -352,14 +352,19 @@ result_list runner::test_one(runner::path_type const& style_path,
} }
map.resize(size.width, size.height); map.resize(size.width, size.height);
if (cfg.bbox.valid())
{ auto bbox = cfg.bbox;
map.zoom_to_box(cfg.bbox); if (!bbox.valid())
}
else
{ {
map.zoom_all(); map.zoom_all();
bbox = map.get_current_extent();
} }
if (size.has_margin())
{
size.inflate_by_margin(bbox);
}
map.zoom_to_box(bbox);
mapnik::util::apply_visitor(renderer_visitor(name, mapnik::util::apply_visitor(renderer_visitor(name,
map, map,
tiles_count, tiles_count,