first stab at moving mutable render request properties out of apply_to_layer

This commit is contained in:
Dane Springmeyer 2013-02-20 19:52:54 -08:00
parent 34708c4df0
commit 2648f8f49a
7 changed files with 323 additions and 10 deletions

View file

@ -34,6 +34,7 @@
#include <mapnik/ctrans.hpp> // for CoordTransform
#include <mapnik/image_compositing.hpp> // for composite_mode_e
#include <mapnik/pixel_position.hpp>
#include <mapnik/request.hpp>
// boost
#include <boost/scoped_ptr.hpp>
@ -69,6 +70,8 @@ public:
// create with external placement detector, possibly non-empty
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);
// create with mapnik.request object that holds request-specific stuff
agg_renderer(Map const& m, request const& req, T & pixmap, double scale_factor=1.0);
~agg_renderer();
void start_map_processing(Map const& map);
void end_map_processing(Map const& map);

View file

@ -68,7 +68,12 @@ public:
void apply_to_layer(layer const& lay,
Processor & p,
projection const& proj0,
double scale,
double scale_denom,
unsigned width,
unsigned height,
box2d<double> const& extent,
int buffer_size,
std::set<std::string>& names);
private:

View file

@ -171,7 +171,17 @@ void feature_style_processor<Processor>::apply()
if (lyr.visible(scale_denom))
{
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))
{
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)
@ -215,7 +234,12 @@ void feature_style_processor<Processor>::apply(mapnik::layer const& lyr, std::se
template <typename Processor>
void feature_style_processor<Processor>::apply_to_layer(layer const& lay, Processor & p,
projection const& proj0,
double scale,
double scale_denom,
unsigned width,
unsigned height,
box2d<double> const& extent,
int buffer_size,
std::set<std::string>& names)
{
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
box2d<double> query_ext = m_.get_current_extent(); // unbuffered
box2d<double> query_ext = extent; // unbuffered
box2d<double> buffered_query_ext(query_ext); // buffered
double buffer_padding = 2.0 * scale;
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
{
double extra = 2.0 * m_.scale() * *layer_buffer_size;
buffered_query_ext.width(query_ext.width() + extra);
buffered_query_ext.height(query_ext.height() + extra);
buffer_padding *= *layer_buffer_size;
}
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
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 qh = query_ext.height()>0 ? query_ext.height() : 1;
query::resolution_type res(m_.width()/qw,
m_.height()/qh);
query::resolution_type res(width/qw,
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*> active_styles;
attribute_collector collector(names);
double filt_factor = 1.0;

128
include/mapnik/request.hpp Normal file
View file

@ -0,0 +1,128 @@
/*****************************************************************************
*
* 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/well_known_srs.hpp>
#include <mapnik/config.hpp>
#include <mapnik/box2d.hpp>
// boost
#include <boost/optional/optional.hpp>
namespace mapnik
{
class MAPNIK_DECL request
{
private:
static const unsigned MIN_MAPSIZE=16;
static const unsigned MAX_MAPSIZE=MIN_MAPSIZE<<10;
unsigned width_;
unsigned height_;
int buffer_size_;
box2d<double> current_extent_;
boost::optional<box2d<double> > maximum_extent_;
public:
/*! \brief Constructor
* @param width Initial map width.
* @param height Initial map height.
* @param srs Initial map projection.
*/
request(int width, int height);
/*! \brief Get map width.
*/
unsigned width() const;
/*! \brief Get map height.
*/
unsigned height() const;
/*! \brief Set map width.
*/
void set_width(unsigned width);
/*! \brief Set map height.
*/
void set_height(unsigned height);
/*! \brief Resize the map.
*/
void resize(unsigned width,unsigned height);
/*! \brief Set buffer size
* @param buffer_size Buffer size in pixels.
*/
void set_buffer_size(int buffer_size);
/*! \brief Get the map buffer size
* @return Buffer size as int
*/
int buffer_size() const;
/*! \brief Set the map maximum extent.
* @param box The bounding box for the maximum extent.
*/
void set_maximum_extent(box2d<double> const& box);
/*! \brief Get the map maximum extent as box2d<double>
*/
boost::optional<box2d<double> > const& maximum_extent() const;
void reset_maximum_extent();
/*! \brief Zoom the map to a bounding box.
*
* Aspect is handled automatic if not fitting to width/height.
* @param box The bounding box where to zoom.
*/
void zoom_to_box(const box2d<double>& box);
/*! \brief Get current bounding box.
* @return The current bounding box.
*/
const box2d<double>& get_current_extent() const;
/*! \brief Get current buffered bounding box.
* @return The current buffered bounding box.
*/
box2d<double> get_buffered_extent() const;
/*!
* @return The Map Scale.
*/
double scale() const;
~request();
private:
};
}
#endif // MAPNIK_REQUEST_HPP

View file

@ -84,6 +84,25 @@ agg_renderer<T>::agg_renderer(Map const& m, T & pixmap, double scale_factor, uns
setup(m);
}
template <typename T>
agg_renderer<T>::agg_renderer(Map const& m, request const& req, T & pixmap, double scale_factor)
: 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.get_current_extent(),0.0,0.0),
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>
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)

View file

@ -100,6 +100,7 @@ else: # unix, non-macos
source = Split(
"""
request.cpp
well_known_srs.cpp
params.cpp
image_filter_types.cpp

132
src/request.cpp Normal file
View file

@ -0,0 +1,132 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2011 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(int width,int height)
: width_(width),
height_(height),
buffer_size_(0) {}
request::~request() {}
unsigned request::width() const
{
return width_;
}
unsigned request::height() const
{
return height_;
}
void request::set_width(unsigned width)
{
if (width != width_ &&
width >= MIN_MAPSIZE &&
width <= MAX_MAPSIZE)
{
width_=width;
}
}
void request::set_height(unsigned height)
{
if (height != height_ &&
height >= MIN_MAPSIZE &&
height <= MAX_MAPSIZE)
{
height_=height;
}
}
void request::resize(unsigned width,unsigned height)
{
if (width != width_ &&
height != height_ &&
width >= MIN_MAPSIZE &&
width <= MAX_MAPSIZE &&
height >= MIN_MAPSIZE &&
height <= MAX_MAPSIZE)
{
width_=width;
height_=height;
}
}
void request::set_buffer_size( int buffer_size)
{
buffer_size_ = buffer_size;
}
int request::buffer_size() const
{
return buffer_size_;
}
void request::set_maximum_extent(box2d<double> const& box)
{
maximum_extent_.reset(box);
}
boost::optional<box2d<double> > const& request::maximum_extent() const
{
return maximum_extent_;
}
void request::reset_maximum_extent()
{
maximum_extent_.reset();
}
void request::zoom_to_box(const box2d<double> &box)
{
current_extent_=box;
}
const box2d<double>& request::get_current_extent() const
{
return current_extent_;
}
box2d<double> request::get_buffered_extent() const
{
double extra = 2.0 * scale() * buffer_size_;
box2d<double> ext(current_extent_);
ext.width(current_extent_.width() + extra);
ext.height(current_extent_.height() + extra);
return ext;
}
double request::scale() const
{
if (width_>0)
return current_extent_.width()/width_;
return current_extent_.width();
}
}