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:
parent
2929c4ae6d
commit
c836e80107
3 changed files with 72 additions and 13 deletions
|
@ -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
|
||||||
|
|
|
@ -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 % ';' ;
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue