Merge pull request #1737 from mapnik/map-request
Rendering hook to allow for passing mutable map properties via mapnik::request object
This commit is contained in:
commit
9f27b02435
16 changed files with 424 additions and 12 deletions
|
@ -34,6 +34,7 @@
|
||||||
#include <mapnik/ctrans.hpp> // for CoordTransform
|
#include <mapnik/ctrans.hpp> // for CoordTransform
|
||||||
#include <mapnik/image_compositing.hpp> // for composite_mode_e
|
#include <mapnik/image_compositing.hpp> // for composite_mode_e
|
||||||
#include <mapnik/pixel_position.hpp>
|
#include <mapnik/pixel_position.hpp>
|
||||||
|
#include <mapnik/request.hpp>
|
||||||
|
|
||||||
// boost
|
// boost
|
||||||
#include <boost/scoped_ptr.hpp>
|
#include <boost/scoped_ptr.hpp>
|
||||||
|
@ -69,6 +70,8 @@ public:
|
||||||
// create with external placement detector, possibly non-empty
|
// create with external placement detector, possibly non-empty
|
||||||
agg_renderer(Map const &m, T & pixmap, boost::shared_ptr<label_collision_detector4> detector,
|
agg_renderer(Map const &m, T & pixmap, boost::shared_ptr<label_collision_detector4> detector,
|
||||||
double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0);
|
double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0);
|
||||||
|
// pass in mapnik::request object to provide the mutable things per render
|
||||||
|
agg_renderer(Map const& m, request const& req, T & pixmap, double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0);
|
||||||
~agg_renderer();
|
~agg_renderer();
|
||||||
void start_map_processing(Map const& map);
|
void start_map_processing(Map const& map);
|
||||||
void end_map_processing(Map const& map);
|
void end_map_processing(Map const& map);
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include <mapnik/font_engine_freetype.hpp>
|
#include <mapnik/font_engine_freetype.hpp>
|
||||||
#include <mapnik/label_collision_detector.hpp>
|
#include <mapnik/label_collision_detector.hpp>
|
||||||
#include <mapnik/map.hpp>
|
#include <mapnik/map.hpp>
|
||||||
|
#include <mapnik/request.hpp>
|
||||||
#include <mapnik/rule.hpp> // for all symbolizers
|
#include <mapnik/rule.hpp> // for all symbolizers
|
||||||
#include <mapnik/noncopyable.hpp>
|
#include <mapnik/noncopyable.hpp>
|
||||||
#include <mapnik/cairo_context.hpp>
|
#include <mapnik/cairo_context.hpp>
|
||||||
|
@ -57,6 +58,7 @@ class MAPNIK_DECL cairo_renderer_base : private mapnik::noncopyable
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
cairo_renderer_base(Map const& m, cairo_ptr const& cairo, double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0);
|
cairo_renderer_base(Map const& m, cairo_ptr const& cairo, double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0);
|
||||||
|
cairo_renderer_base(Map const& m, request const& req, cairo_ptr const& cairo, double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0);
|
||||||
cairo_renderer_base(Map const& m, cairo_ptr const& cairo, boost::shared_ptr<label_collision_detector4> detector, double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0);
|
cairo_renderer_base(Map const& m, cairo_ptr const& cairo, boost::shared_ptr<label_collision_detector4> detector, double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0);
|
||||||
public:
|
public:
|
||||||
~cairo_renderer_base();
|
~cairo_renderer_base();
|
||||||
|
@ -137,6 +139,7 @@ class MAPNIK_DECL cairo_renderer : public feature_style_processor<cairo_renderer
|
||||||
public:
|
public:
|
||||||
typedef cairo_renderer_base processor_impl_type;
|
typedef cairo_renderer_base processor_impl_type;
|
||||||
cairo_renderer(Map const& m, T const& obj, double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0);
|
cairo_renderer(Map const& m, T const& obj, double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0);
|
||||||
|
cairo_renderer(Map const& m, request const& req, T const& obj, double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0);
|
||||||
cairo_renderer(Map const& m, T const& obj, boost::shared_ptr<label_collision_detector4> detector, double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0);
|
cairo_renderer(Map const& m, T const& obj, boost::shared_ptr<label_collision_detector4> detector, double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0);
|
||||||
void end_map_processing(Map const& map);
|
void end_map_processing(Map const& map);
|
||||||
};
|
};
|
||||||
|
|
|
@ -69,7 +69,12 @@ public:
|
||||||
void apply_to_layer(layer const& lay,
|
void apply_to_layer(layer const& lay,
|
||||||
Processor & p,
|
Processor & p,
|
||||||
projection const& proj0,
|
projection const& proj0,
|
||||||
|
double scale,
|
||||||
double scale_denom,
|
double scale_denom,
|
||||||
|
unsigned width,
|
||||||
|
unsigned height,
|
||||||
|
box2d<double> const& extent,
|
||||||
|
int buffer_size,
|
||||||
std::set<std::string>& names);
|
std::set<std::string>& names);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -171,7 +171,17 @@ void feature_style_processor<Processor>::apply()
|
||||||
if (lyr.visible(scale_denom))
|
if (lyr.visible(scale_denom))
|
||||||
{
|
{
|
||||||
std::set<std::string> names;
|
std::set<std::string> names;
|
||||||
apply_to_layer(lyr, p, proj, scale_denom, names);
|
apply_to_layer(lyr,
|
||||||
|
p,
|
||||||
|
proj,
|
||||||
|
m_.scale(),
|
||||||
|
scale_denom,
|
||||||
|
m_.width(),
|
||||||
|
m_.height(),
|
||||||
|
m_.get_current_extent(),
|
||||||
|
m_.buffer_size(),
|
||||||
|
names);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -202,7 +212,16 @@ void feature_style_processor<Processor>::apply(mapnik::layer const& lyr, std::se
|
||||||
|
|
||||||
if (lyr.visible(scale_denom))
|
if (lyr.visible(scale_denom))
|
||||||
{
|
{
|
||||||
apply_to_layer(lyr, p, proj, scale_denom, names);
|
apply_to_layer(lyr,
|
||||||
|
p,
|
||||||
|
proj,
|
||||||
|
m_.scale(),
|
||||||
|
scale_denom,
|
||||||
|
m_.width(),
|
||||||
|
m_.height(),
|
||||||
|
m_.get_current_extent(),
|
||||||
|
m_.buffer_size(),
|
||||||
|
names);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (proj_init_error& ex)
|
catch (proj_init_error& ex)
|
||||||
|
@ -215,7 +234,12 @@ void feature_style_processor<Processor>::apply(mapnik::layer const& lyr, std::se
|
||||||
template <typename Processor>
|
template <typename Processor>
|
||||||
void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Processor & p,
|
void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Processor & p,
|
||||||
projection const& proj0,
|
projection const& proj0,
|
||||||
|
double scale,
|
||||||
double scale_denom,
|
double scale_denom,
|
||||||
|
unsigned width,
|
||||||
|
unsigned height,
|
||||||
|
box2d<double> const& extent,
|
||||||
|
int buffer_size,
|
||||||
std::set<std::string>& names)
|
std::set<std::string>& names)
|
||||||
{
|
{
|
||||||
std::vector<std::string> const& style_names = lay.styles();
|
std::vector<std::string> const& style_names = lay.styles();
|
||||||
|
@ -253,20 +277,21 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
box2d<double> query_ext = m_.get_current_extent(); // unbuffered
|
box2d<double> query_ext = extent; // unbuffered
|
||||||
box2d<double> buffered_query_ext(query_ext); // buffered
|
box2d<double> buffered_query_ext(query_ext); // buffered
|
||||||
|
|
||||||
|
double buffer_padding = 2.0 * scale;
|
||||||
boost::optional<int> layer_buffer_size = lay.buffer_size();
|
boost::optional<int> layer_buffer_size = lay.buffer_size();
|
||||||
if (layer_buffer_size) // if layer overrides buffer size, use this value to compute buffered extent
|
if (layer_buffer_size) // if layer overrides buffer size, use this value to compute buffered extent
|
||||||
{
|
{
|
||||||
double extra = 2.0 * m_.scale() * *layer_buffer_size;
|
buffer_padding *= *layer_buffer_size;
|
||||||
buffered_query_ext.width(query_ext.width() + extra);
|
|
||||||
buffered_query_ext.height(query_ext.height() + extra);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
buffered_query_ext = m_.get_buffered_extent();
|
buffer_padding *= buffer_size;
|
||||||
}
|
}
|
||||||
|
buffered_query_ext.width(query_ext.width() + buffer_padding);
|
||||||
|
buffered_query_ext.height(query_ext.height() + buffer_padding);
|
||||||
|
|
||||||
// clip buffered extent by maximum extent, if supplied
|
// clip buffered extent by maximum extent, if supplied
|
||||||
boost::optional<box2d<double> > const& maximum_extent = m_.maximum_extent();
|
boost::optional<box2d<double> > const& maximum_extent = m_.maximum_extent();
|
||||||
|
@ -363,10 +388,10 @@ void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Proces
|
||||||
|
|
||||||
double qw = query_ext.width()>0 ? query_ext.width() : 1;
|
double qw = query_ext.width()>0 ? query_ext.width() : 1;
|
||||||
double qh = query_ext.height()>0 ? query_ext.height() : 1;
|
double qh = query_ext.height()>0 ? query_ext.height() : 1;
|
||||||
query::resolution_type res(m_.width()/qw,
|
query::resolution_type res(width/qw,
|
||||||
m_.height()/qh);
|
height/qh);
|
||||||
|
|
||||||
query q(layer_ext,res,scale_denom,m_.get_current_extent());
|
query q(layer_ext,res,scale_denom,extent);
|
||||||
std::vector<feature_type_style const*> active_styles;
|
std::vector<feature_type_style const*> active_styles;
|
||||||
attribute_collector collector(names);
|
attribute_collector collector(names);
|
||||||
double filt_factor = 1.0;
|
double filt_factor = 1.0;
|
||||||
|
|
|
@ -53,6 +53,7 @@ namespace mapnik {
|
||||||
class marker;
|
class marker;
|
||||||
class proj_transform;
|
class proj_transform;
|
||||||
struct grid_rasterizer;
|
struct grid_rasterizer;
|
||||||
|
class request;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace mapnik {
|
namespace mapnik {
|
||||||
|
@ -66,6 +67,7 @@ public:
|
||||||
typedef T buffer_type;
|
typedef T buffer_type;
|
||||||
typedef grid_renderer<T> processor_impl_type;
|
typedef grid_renderer<T> processor_impl_type;
|
||||||
grid_renderer(Map const& m, T & pixmap, double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0);
|
grid_renderer(Map const& m, T & pixmap, double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0);
|
||||||
|
grid_renderer(Map const& m, request const& req, T & pixmap, double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0);
|
||||||
~grid_renderer();
|
~grid_renderer();
|
||||||
void start_map_processing(Map const& map);
|
void start_map_processing(Map const& map);
|
||||||
void end_map_processing(Map const& map);
|
void end_map_processing(Map const& map);
|
||||||
|
|
60
include/mapnik/request.hpp
Normal file
60
include/mapnik/request.hpp
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Artem Pavlenko
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef MAPNIK_REQUEST_HPP
|
||||||
|
#define MAPNIK_REQUEST_HPP
|
||||||
|
|
||||||
|
// mapnik
|
||||||
|
#include <mapnik/config.hpp>
|
||||||
|
#include <mapnik/box2d.hpp>
|
||||||
|
|
||||||
|
// boost
|
||||||
|
#include <boost/optional/optional.hpp>
|
||||||
|
|
||||||
|
namespace mapnik
|
||||||
|
{
|
||||||
|
|
||||||
|
class MAPNIK_DECL request
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
request(unsigned width,
|
||||||
|
unsigned height,
|
||||||
|
box2d<double> const& extent);
|
||||||
|
unsigned width() const;
|
||||||
|
unsigned height() const;
|
||||||
|
void set_buffer_size(int buffer_size);
|
||||||
|
int buffer_size() const;
|
||||||
|
box2d<double> const& extent() const;
|
||||||
|
void set_extent(box2d<double> const& box);
|
||||||
|
box2d<double> get_buffered_extent() const;
|
||||||
|
double scale() const;
|
||||||
|
~request();
|
||||||
|
private:
|
||||||
|
unsigned width_;
|
||||||
|
unsigned height_;
|
||||||
|
box2d<double> extent_;
|
||||||
|
int buffer_size_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // MAPNIK_REQUEST_HPP
|
|
@ -84,6 +84,25 @@ agg_renderer<T>::agg_renderer(Map const& m, T & pixmap, double scale_factor, uns
|
||||||
setup(m);
|
setup(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
agg_renderer<T>::agg_renderer(Map const& m, request const& req, T & pixmap, double scale_factor, unsigned offset_x, unsigned offset_y)
|
||||||
|
: feature_style_processor<agg_renderer>(m, scale_factor),
|
||||||
|
pixmap_(pixmap),
|
||||||
|
internal_buffer_(),
|
||||||
|
current_buffer_(&pixmap),
|
||||||
|
style_level_compositing_(false),
|
||||||
|
width_(pixmap_.width()),
|
||||||
|
height_(pixmap_.height()),
|
||||||
|
scale_factor_(scale_factor),
|
||||||
|
t_(req.width(),req.height(),req.extent(),offset_x,offset_y),
|
||||||
|
font_engine_(),
|
||||||
|
font_manager_(font_engine_),
|
||||||
|
detector_(boost::make_shared<label_collision_detector4>(box2d<double>(-req.buffer_size(), -req.buffer_size(), req.width() + req.buffer_size() ,req.height() + req.buffer_size()))),
|
||||||
|
ras_ptr(new rasterizer)
|
||||||
|
{
|
||||||
|
setup(m);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
agg_renderer<T>::agg_renderer(Map const& m, T & pixmap, boost::shared_ptr<label_collision_detector4> detector,
|
agg_renderer<T>::agg_renderer(Map const& m, T & pixmap, boost::shared_ptr<label_collision_detector4> detector,
|
||||||
double scale_factor, unsigned offset_x, unsigned offset_y)
|
double scale_factor, unsigned offset_x, unsigned offset_y)
|
||||||
|
|
|
@ -109,6 +109,7 @@ else: # unix, non-macos
|
||||||
|
|
||||||
source = Split(
|
source = Split(
|
||||||
"""
|
"""
|
||||||
|
request.cpp
|
||||||
well_known_srs.cpp
|
well_known_srs.cpp
|
||||||
params.cpp
|
params.cpp
|
||||||
image_filter_types.cpp
|
image_filter_types.cpp
|
||||||
|
|
|
@ -210,7 +210,7 @@ void cairo_context::set_dash(dash_array const &dashes, double scale_factor)
|
||||||
d[index++] = itr->second * scale_factor;
|
d[index++] = itr->second * scale_factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_set_dash(cairo_.get() , &d[0], dashes.size(), 0/*offset*/);
|
cairo_set_dash(cairo_.get() , &d[0], d.size(), 0/*offset*/);
|
||||||
check_object_status_and_throw_exception(*this);
|
check_object_status_and_throw_exception(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -140,6 +140,28 @@ cairo_renderer_base::cairo_renderer_base(Map const& m,
|
||||||
setup(m);
|
setup(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cairo_renderer_base::cairo_renderer_base(Map const& m,
|
||||||
|
request const& req,
|
||||||
|
cairo_ptr const& cairo,
|
||||||
|
double scale_factor,
|
||||||
|
unsigned offset_x,
|
||||||
|
unsigned offset_y)
|
||||||
|
: m_(m),
|
||||||
|
context_(cairo),
|
||||||
|
width_(req.width()),
|
||||||
|
height_(req.height()),
|
||||||
|
scale_factor_(scale_factor),
|
||||||
|
t_(req.width(),req.height(),req.extent(),offset_x,offset_y),
|
||||||
|
font_engine_(boost::make_shared<freetype_engine>()),
|
||||||
|
font_manager_(*font_engine_),
|
||||||
|
face_manager_(font_engine_),
|
||||||
|
detector_(boost::make_shared<label_collision_detector4>(
|
||||||
|
box2d<double>(-req.buffer_size(), -req.buffer_size(),
|
||||||
|
req.width() + req.buffer_size(), req.height() + req.buffer_size())))
|
||||||
|
{
|
||||||
|
setup(m);
|
||||||
|
}
|
||||||
|
|
||||||
cairo_renderer_base::cairo_renderer_base(Map const& m,
|
cairo_renderer_base::cairo_renderer_base(Map const& m,
|
||||||
cairo_ptr const& cairo,
|
cairo_ptr const& cairo,
|
||||||
boost::shared_ptr<label_collision_detector4> detector,
|
boost::shared_ptr<label_collision_detector4> detector,
|
||||||
|
@ -170,6 +192,16 @@ cairo_renderer<cairo_surface_ptr>::cairo_renderer(Map const& m, cairo_surface_pt
|
||||||
: feature_style_processor<cairo_renderer>(m,scale_factor),
|
: feature_style_processor<cairo_renderer>(m,scale_factor),
|
||||||
cairo_renderer_base(m,create_context(surface),scale_factor,offset_x,offset_y) {}
|
cairo_renderer_base(m,create_context(surface),scale_factor,offset_x,offset_y) {}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
cairo_renderer<cairo_ptr>::cairo_renderer(Map const& m, request const& req, cairo_ptr const& cairo, double scale_factor, unsigned offset_x, unsigned offset_y)
|
||||||
|
: feature_style_processor<cairo_renderer>(m,scale_factor),
|
||||||
|
cairo_renderer_base(m,req,cairo,scale_factor,offset_x,offset_y) {}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
cairo_renderer<cairo_surface_ptr>::cairo_renderer(Map const& m, request const& req, cairo_surface_ptr const& surface, double scale_factor, unsigned offset_x, unsigned offset_y)
|
||||||
|
: feature_style_processor<cairo_renderer>(m,scale_factor),
|
||||||
|
cairo_renderer_base(m,req, create_context(surface),scale_factor,offset_x,offset_y) {}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
cairo_renderer<cairo_ptr>::cairo_renderer(Map const& m, cairo_ptr const& cairo, boost::shared_ptr<label_collision_detector4> detector, double scale_factor, unsigned offset_x, unsigned offset_y)
|
cairo_renderer<cairo_ptr>::cairo_renderer(Map const& m, cairo_ptr const& cairo, boost::shared_ptr<label_collision_detector4> detector, double scale_factor, unsigned offset_x, unsigned offset_y)
|
||||||
: feature_style_processor<cairo_renderer>(m,scale_factor),
|
: feature_style_processor<cairo_renderer>(m,scale_factor),
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include <mapnik/font_set.hpp>
|
#include <mapnik/font_set.hpp>
|
||||||
#include <mapnik/parse_path.hpp>
|
#include <mapnik/parse_path.hpp>
|
||||||
#include <mapnik/map.hpp>
|
#include <mapnik/map.hpp>
|
||||||
|
#include <mapnik/request.hpp>
|
||||||
#include <mapnik/svg/svg_converter.hpp>
|
#include <mapnik/svg/svg_converter.hpp>
|
||||||
#include <mapnik/svg/svg_renderer_agg.hpp>
|
#include <mapnik/svg/svg_renderer_agg.hpp>
|
||||||
#include <mapnik/svg/svg_path_adapter.hpp>
|
#include <mapnik/svg/svg_path_adapter.hpp>
|
||||||
|
@ -71,6 +72,24 @@ grid_renderer<T>::grid_renderer(Map const& m, T & pixmap, double scale_factor, u
|
||||||
setup(m);
|
setup(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
grid_renderer<T>::grid_renderer(Map const& m, request const& req, T & pixmap, double scale_factor, unsigned offset_x, unsigned offset_y)
|
||||||
|
: feature_style_processor<grid_renderer>(m, scale_factor),
|
||||||
|
pixmap_(pixmap),
|
||||||
|
width_(pixmap_.width()),
|
||||||
|
height_(pixmap_.height()),
|
||||||
|
scale_factor_(scale_factor),
|
||||||
|
// NOTE: can change this to m dims instead of pixmap_ if render-time
|
||||||
|
// resolution support is dropped from grid_renderer python interface
|
||||||
|
t_(pixmap_.width(),pixmap_.height(),req.extent(),offset_x,offset_y),
|
||||||
|
font_engine_(),
|
||||||
|
font_manager_(font_engine_),
|
||||||
|
detector_(boost::make_shared<label_collision_detector4>(box2d<double>(-req.buffer_size(), -req.buffer_size(), req.width() + req.buffer_size() ,req.height() + req.buffer_size()))),
|
||||||
|
ras_ptr(new grid_rasterizer)
|
||||||
|
{
|
||||||
|
setup(m);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void grid_renderer<T>::setup(Map const& m)
|
void grid_renderer<T>::setup(Map const& m)
|
||||||
{
|
{
|
||||||
|
|
85
src/request.cpp
Normal file
85
src/request.cpp
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Artem Pavlenko
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
// mapnik
|
||||||
|
#include <mapnik/request.hpp>
|
||||||
|
|
||||||
|
namespace mapnik
|
||||||
|
{
|
||||||
|
|
||||||
|
request::request(unsigned width,
|
||||||
|
unsigned height,
|
||||||
|
box2d<double> const& extent)
|
||||||
|
: width_(width),
|
||||||
|
height_(height),
|
||||||
|
extent_(extent),
|
||||||
|
buffer_size_(0) {}
|
||||||
|
|
||||||
|
request::~request() {}
|
||||||
|
|
||||||
|
unsigned request::width() const
|
||||||
|
{
|
||||||
|
return width_;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned request::height() const
|
||||||
|
{
|
||||||
|
return height_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void request::set_buffer_size(int buffer_size)
|
||||||
|
{
|
||||||
|
buffer_size_ = buffer_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int request::buffer_size() const
|
||||||
|
{
|
||||||
|
return buffer_size_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void request::set_extent(box2d<double> const& box)
|
||||||
|
{
|
||||||
|
extent_ = box;
|
||||||
|
}
|
||||||
|
|
||||||
|
box2d<double> const& request::extent() const
|
||||||
|
{
|
||||||
|
return extent_;
|
||||||
|
}
|
||||||
|
|
||||||
|
box2d<double> request::get_buffered_extent() const
|
||||||
|
{
|
||||||
|
double extra = 2.0 * scale() * buffer_size_;
|
||||||
|
box2d<double> ext(extent_);
|
||||||
|
ext.width(extent_.width() + extra);
|
||||||
|
ext.height(extent_.height() + extra);
|
||||||
|
return ext;
|
||||||
|
}
|
||||||
|
|
||||||
|
double request::scale() const
|
||||||
|
{
|
||||||
|
if (width_>0)
|
||||||
|
return extent_.width()/width_;
|
||||||
|
return extent_.width();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -11,6 +11,12 @@ test_env.AppendUnique(LIBS='mapnik')
|
||||||
test_env.AppendUnique(LIBS='sqlite3')
|
test_env.AppendUnique(LIBS='sqlite3')
|
||||||
test_env.AppendUnique(CXXFLAGS='-g')
|
test_env.AppendUnique(CXXFLAGS='-g')
|
||||||
|
|
||||||
|
test_env['CXXFLAGS'] = copy(test_env['LIBMAPNIK_CXXFLAGS'])
|
||||||
|
|
||||||
|
if test_env['HAS_CAIRO']:
|
||||||
|
test_env.PrependUnique(CPPPATH=test_env['CAIRO_CPPPATHS'])
|
||||||
|
test_env.Append(CXXFLAGS = '-DHAVE_CAIRO')
|
||||||
|
|
||||||
for cpp_test in glob.glob('*_test.cpp'):
|
for cpp_test in glob.glob('*_test.cpp'):
|
||||||
name = cpp_test.replace('.cpp','-bin')
|
name = cpp_test.replace('.cpp','-bin')
|
||||||
source_files = [cpp_test]
|
source_files = [cpp_test]
|
||||||
|
|
152
tests/cpp_tests/map_request_test.cpp
Normal file
152
tests/cpp_tests/map_request_test.cpp
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
#include <boost/version.hpp>
|
||||||
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <mapnik/map.hpp>
|
||||||
|
#include <mapnik/load_map.hpp>
|
||||||
|
#include <mapnik/agg_renderer.hpp>
|
||||||
|
#if defined(HAVE_CAIRO)
|
||||||
|
#include <mapnik/cairo_renderer.hpp>
|
||||||
|
#include <mapnik/cairo_context.hpp>
|
||||||
|
#endif
|
||||||
|
#include <mapnik/graphics.hpp>
|
||||||
|
#include <mapnik/image_util.hpp>
|
||||||
|
#include <mapnik/datasource_cache.hpp>
|
||||||
|
#include <mapnik/font_engine_freetype.hpp>
|
||||||
|
#include <mapnik/image_data.hpp>
|
||||||
|
#include <mapnik/image_reader.hpp>
|
||||||
|
#include <mapnik/scale_denominator.hpp>
|
||||||
|
#include <mapnik/feature_style_processor.hpp>
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
|
bool compare_images(std::string const& src_fn,std::string const& dest_fn)
|
||||||
|
{
|
||||||
|
using namespace mapnik;
|
||||||
|
std::auto_ptr<mapnik::image_reader> reader1(mapnik::get_image_reader(dest_fn,"png"));
|
||||||
|
if (!reader1.get())
|
||||||
|
{
|
||||||
|
throw mapnik::image_reader_exception("Failed to load: " + dest_fn);
|
||||||
|
}
|
||||||
|
boost::shared_ptr<image_32> image_ptr1 = boost::make_shared<image_32>(reader1->width(),reader1->height());
|
||||||
|
reader1->read(0,0,image_ptr1->data());
|
||||||
|
|
||||||
|
std::auto_ptr<mapnik::image_reader> reader2(mapnik::get_image_reader(src_fn,"png"));
|
||||||
|
if (!reader2.get())
|
||||||
|
{
|
||||||
|
throw mapnik::image_reader_exception("Failed to load: " + src_fn);
|
||||||
|
}
|
||||||
|
boost::shared_ptr<image_32> image_ptr2 = boost::make_shared<image_32>(reader2->width(),reader2->height());
|
||||||
|
reader2->read(0,0,image_ptr2->data());
|
||||||
|
|
||||||
|
image_data_32 const& dest = image_ptr1->data();
|
||||||
|
image_data_32 const& src = image_ptr2->data();
|
||||||
|
|
||||||
|
unsigned int width = src.width();
|
||||||
|
unsigned int height = src.height();
|
||||||
|
if ((width != dest.width()) || height != dest.height()) return false;
|
||||||
|
for (unsigned int y = 0; y < height; ++y)
|
||||||
|
{
|
||||||
|
const unsigned int* row_from = src.getRow(y);
|
||||||
|
const unsigned int* row_to = dest.getRow(y);
|
||||||
|
for (unsigned int x = 0; x < width; ++x)
|
||||||
|
{
|
||||||
|
if (row_from[x] != row_to[x]) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main( int, char*[] )
|
||||||
|
{
|
||||||
|
std::string expected("./tests/cpp_tests/support/map-request-marker-text-line-expected.png");
|
||||||
|
std::string expected_cairo("./tests/cpp_tests/support/map-request-marker-text-line-expected-cairo.png");
|
||||||
|
try {
|
||||||
|
mapnik::datasource_cache::instance().register_datasources("./plugins/input/");
|
||||||
|
mapnik::freetype_engine::register_fonts("./fonts", true );
|
||||||
|
mapnik::Map m(256,256);
|
||||||
|
mapnik::load_map(m,"./tests/data/good_maps/marker-text-line.xml",false);
|
||||||
|
m.zoom_all();
|
||||||
|
mapnik::image_32 im(m.width(),m.height());
|
||||||
|
double scale_factor = 1.2;
|
||||||
|
|
||||||
|
// render normally with apply() and just map and image
|
||||||
|
mapnik::agg_renderer<mapnik::image_32> renderer1(m,im,scale_factor);
|
||||||
|
renderer1.apply();
|
||||||
|
std::string actual1("/tmp/map-request-marker-text-line-actual1.png");
|
||||||
|
//mapnik::save_to_file(im,expected);
|
||||||
|
mapnik::save_to_file(im,actual1);
|
||||||
|
BOOST_TEST(compare_images(actual1,expected));
|
||||||
|
|
||||||
|
// reset image
|
||||||
|
im.clear();
|
||||||
|
|
||||||
|
// set up a mapnik::request object
|
||||||
|
mapnik::request req(m.width(),m.height(),m.get_current_extent());
|
||||||
|
req.set_buffer_size(m.buffer_size());
|
||||||
|
|
||||||
|
// render using apply() and mapnik::request
|
||||||
|
mapnik::agg_renderer<mapnik::image_32> renderer2(m,req,im,scale_factor);
|
||||||
|
renderer2.apply();
|
||||||
|
std::string actual2("/tmp/map-request-marker-text-line-actual2.png");
|
||||||
|
mapnik::save_to_file(im,actual2);
|
||||||
|
BOOST_TEST(compare_images(actual2,expected));
|
||||||
|
|
||||||
|
// reset image
|
||||||
|
im.clear();
|
||||||
|
|
||||||
|
// render with apply_to_layer api and mapnik::request params passed to apply_to_layer
|
||||||
|
mapnik::agg_renderer<mapnik::image_32> renderer3(m,req,im,scale_factor);
|
||||||
|
renderer3.start_map_processing(m);
|
||||||
|
mapnik::projection map_proj(m.srs(),true);
|
||||||
|
double scale_denom = mapnik::scale_denominator(req.scale(),map_proj.is_geographic());
|
||||||
|
scale_denom *= scale_factor;
|
||||||
|
BOOST_FOREACH ( mapnik::layer const& lyr, m.layers() )
|
||||||
|
{
|
||||||
|
if (lyr.visible(scale_denom))
|
||||||
|
{
|
||||||
|
std::set<std::string> names;
|
||||||
|
renderer3.apply_to_layer(lyr,
|
||||||
|
renderer3,
|
||||||
|
map_proj,
|
||||||
|
req.scale(),
|
||||||
|
scale_denom,
|
||||||
|
req.width(),
|
||||||
|
req.height(),
|
||||||
|
req.extent(),
|
||||||
|
req.buffer_size(),
|
||||||
|
names);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
renderer3.end_map_processing(m);
|
||||||
|
std::string actual3("/tmp/map-request-marker-text-line-actual3.png");
|
||||||
|
mapnik::save_to_file(im,actual3);
|
||||||
|
BOOST_TEST(compare_images(actual3,expected));
|
||||||
|
|
||||||
|
// also test cairo
|
||||||
|
#if defined(HAVE_CAIRO)
|
||||||
|
mapnik::cairo_surface_ptr image_surface(
|
||||||
|
cairo_image_surface_create(CAIRO_FORMAT_ARGB32,req.width(),req.height()),
|
||||||
|
mapnik::cairo_surface_closer());
|
||||||
|
mapnik::cairo_ptr image_context = (mapnik::create_context(image_surface));
|
||||||
|
mapnik::cairo_renderer<mapnik::cairo_ptr> png_render(m,req,image_context,scale_factor);
|
||||||
|
png_render.apply();
|
||||||
|
//cairo_surface_write_to_png(&*image_surface, expected_cairo.c_str());
|
||||||
|
std::string actual_cairo("/tmp/map-request-marker-text-line-actual4.png");
|
||||||
|
cairo_surface_write_to_png(&*image_surface, actual_cairo.c_str());
|
||||||
|
BOOST_TEST(compare_images(actual_cairo,expected_cairo));
|
||||||
|
#endif
|
||||||
|
// TODO - test grid_renderer
|
||||||
|
|
||||||
|
} catch (std::exception const& ex) {
|
||||||
|
std::clog << ex.what() << "\n";
|
||||||
|
}
|
||||||
|
if (!::boost::detail::test_errors()) {
|
||||||
|
std::clog << "C++ Map Request rendering hook: \x1b[1;32m✓ \x1b[0m\n";
|
||||||
|
#if BOOST_VERSION >= 104600
|
||||||
|
::boost::detail::report_errors_remind().called_report_errors_function = true;
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
return ::boost::report_errors();
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
|
@ -1,4 +1,4 @@
|
||||||
<Map>
|
<Map srs="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs">
|
||||||
<Style name="ellipse">
|
<Style name="ellipse">
|
||||||
<Rule>
|
<Rule>
|
||||||
<MarkersSymbolizer
|
<MarkersSymbolizer
|
||||||
|
|
Loading…
Reference in a new issue