Merge pull request #2251 from mapnik/render-time-variables

[WIP] Render time variables
This commit is contained in:
Dane Springmeyer 2014-05-22 19:56:32 -07:00
commit 051878c529
89 changed files with 924 additions and 585 deletions

View file

@ -15,11 +15,11 @@ before_install:
# grab more recent gdal/proj # grab more recent gdal/proj
- sudo add-apt-repository -y ppa:ubuntugis/ubuntugis-unstable - sudo add-apt-repository -y ppa:ubuntugis/ubuntugis-unstable
# more recent boost # more recent boost
- sudo add-apt-repository -y ppa:mapnik/boost - sudo add-apt-repository -y ppa:boost-latest/ppa
- sudo apt-get update -y - sudo apt-get update -y
# upgrade compilers # upgrade compilers
- sudo apt-get install -y gcc-4.8 g++-4.8 - sudo apt-get install -y gcc-4.8 g++-4.8
- sudo apt-get install -y make libboost-dev libboost-filesystem-dev libboost-program-options-dev libboost-python-dev libboost-regex-dev libboost-system-dev libboost-thread-dev python-nose libicu-dev libpng-dev libjpeg-dev libtiff-dev libwebp-dev libz-dev libfreetype6-dev libxml2-dev libproj-dev libcairo-dev python-cairo-dev libsqlite3-dev - sudo apt-get install -y make boost1.55 libgdal-dev python-nose libicu-dev libpng-dev libjpeg-dev libtiff-dev libwebp-dev libz-dev libfreetype6-dev libxml2-dev libproj-dev libcairo-dev python-cairo-dev libsqlite3-dev
- wget http://mapnik.s3.amazonaws.com/deps/harfbuzz-0.9.24.tar.bz2 - wget http://mapnik.s3.amazonaws.com/deps/harfbuzz-0.9.24.tar.bz2
- tar xf harfbuzz-0.9.24.tar.bz2 - tar xf harfbuzz-0.9.24.tar.bz2
- cd harfbuzz-0.9.24 - cd harfbuzz-0.9.24

View file

@ -52,7 +52,7 @@
</Style> </Style>
<Style name="labels"> <Style name="labels">
<Rule> <Rule>
<TextSymbolizer placement="line" face-name="DejaVu Sans Book" halo-radius="2" allow-overlap="true">[type]</TextSymbolizer> <TextSymbolizer halo-rasterizer="fast" placement="line" face-name="DejaVu Sans Book" halo-radius="2" allow-overlap="true">[type]</TextSymbolizer>
</Rule> </Rule>
</Style> </Style>
<Layer name="layer" <Layer name="layer"

View file

@ -27,6 +27,7 @@
#include "agg_scanline_u.h" #include "agg_scanline_u.h"
#include "agg_renderer_scanline.h" #include "agg_renderer_scanline.h"
#include <mapnik/image_util.hpp> #include <mapnik/image_util.hpp>
#include <fstream>
void render(mapnik::geometry_type & geom, void render(mapnik::geometry_type & geom,
mapnik::box2d<double> const& extent, mapnik::box2d<double> const& extent,

View file

@ -267,15 +267,17 @@ class _Path(Path,_injector):
class _Datasource(Datasource,_injector): class _Datasource(Datasource,_injector):
def all_features(self,fields=None): def all_features(self,fields=None,variables={}):
query = Query(self.envelope()) query = Query(self.envelope())
query.set_variables(variables);
attributes = fields or self.fields() attributes = fields or self.fields()
for fld in attributes: for fld in attributes:
query.add_property_name(fld) query.add_property_name(fld)
return self.features(query).features return self.features(query).features
def featureset(self,fields=None): def featureset(self,fields=None,variables={}):
query = Query(self.envelope()) query = Query(self.envelope())
query.set_variables(variables);
attributes = fields or self.fields() attributes = fields or self.fields()
for fld in attributes: for fld in attributes:
query.add_property_name(fld) query.add_property_name(fld)

View file

@ -21,6 +21,7 @@
*****************************************************************************/ *****************************************************************************/
#include "boost_std_shared_shim.hpp" #include "boost_std_shared_shim.hpp"
#include "python_to_value.hpp"
// boost // boost
#include <boost/python.hpp> #include <boost/python.hpp>
@ -53,15 +54,15 @@ std::string expression_to_string_(mapnik::expr_node const& expr)
return mapnik::to_expression_string(expr); return mapnik::to_expression_string(expr);
} }
mapnik::value expression_evaluate_(mapnik::expr_node const& expr, mapnik::feature_impl const& f) mapnik::value expression_evaluate_(mapnik::expr_node const& expr, mapnik::feature_impl const& f, boost::python::dict const& d)
{ {
// will be auto-converted to proper python type by `mapnik_value_to_python` // will be auto-converted to proper python type by `mapnik_value_to_python`
return boost::apply_visitor(mapnik::evaluate<mapnik::feature_impl,mapnik::value>(f),expr); return boost::apply_visitor(mapnik::evaluate<mapnik::feature_impl,mapnik::value,mapnik::attributes>(f,mapnik::dict2attr(d)),expr);
} }
bool expression_evaluate_to_bool_(mapnik::expr_node const& expr, mapnik::feature_impl const& f) bool expression_evaluate_to_bool_(mapnik::expr_node const& expr, mapnik::feature_impl const& f, boost::python::dict const& d)
{ {
return boost::apply_visitor(mapnik::evaluate<mapnik::feature_impl,mapnik::value>(f),expr).to_bool(); return boost::apply_visitor(mapnik::evaluate<mapnik::feature_impl,mapnik::value,mapnik::attributes>(f,mapnik::dict2attr(d)),expr).to_bool();
} }
// path expression // path expression
@ -86,8 +87,8 @@ void export_expression()
class_<mapnik::expr_node ,boost::noncopyable>("Expression", class_<mapnik::expr_node ,boost::noncopyable>("Expression",
"TODO" "TODO"
"",no_init) "",no_init)
.def("evaluate", &expression_evaluate_) .def("evaluate", &expression_evaluate_,(arg("feature"),arg("variables")=boost::python::dict()))
.def("to_bool", &expression_evaluate_to_bool_) .def("to_bool", &expression_evaluate_to_bool_,(arg("feature"),arg("variables")=boost::python::dict()))
.def("__str__",&expression_to_string_); .def("__str__",&expression_to_string_);
; ;

View file

@ -21,6 +21,7 @@
*****************************************************************************/ *****************************************************************************/
#include "boost_std_shared_shim.hpp" #include "boost_std_shared_shim.hpp"
#include "python_to_value.hpp"
#include <boost/python/args.hpp> // for keywords, arg, etc #include <boost/python/args.hpp> // for keywords, arg, etc
#include <boost/python/converter/from_python.hpp> #include <boost/python/converter/from_python.hpp>
#include <boost/python/def.hpp> // for def #include <boost/python/def.hpp> // for def
@ -182,7 +183,18 @@ void render(mapnik::Map const& map,
python_unblock_auto_block b; python_unblock_auto_block b;
mapnik::agg_renderer<mapnik::image_32> ren(map,image,scale_factor,offset_x, offset_y); mapnik::agg_renderer<mapnik::image_32> ren(map,image,scale_factor,offset_x, offset_y);
ren.apply(); ren.apply();
}
void render_with_vars(mapnik::Map const& map,
mapnik::image_32& image,
boost::python::dict const& d)
{
mapnik::attributes vars = mapnik::dict2attr(d);
mapnik::request req(map.width(),map.height(),map.get_current_extent());
req.set_buffer_size(map.buffer_size());
python_unblock_auto_block b;
mapnik::agg_renderer<mapnik::image_32> ren(map,req,vars,image,1,0,0);
ren.apply();
} }
void render_with_detector( void render_with_detector(
@ -259,7 +271,6 @@ void render6(mapnik::Map const& map, PycairoContext* py_context)
mapnik::cairo_renderer<mapnik::cairo_ptr> ren(map,context); mapnik::cairo_renderer<mapnik::cairo_ptr> ren(map,context);
ren.apply(); ren.apply();
} }
void render_with_detector2( void render_with_detector2(
mapnik::Map const& map, mapnik::Map const& map,
PycairoContext* py_context, PycairoContext* py_context,
@ -647,6 +658,7 @@ BOOST_PYTHON_MODULE(_mapnik)
"\n" "\n"
); );
def("render_with_vars",&render_with_vars);
def("render", &render, render_overloads( def("render", &render, render_overloads(
"\n" "\n"

View file

@ -21,6 +21,7 @@
*****************************************************************************/ *****************************************************************************/
#include "boost_std_shared_shim.hpp" #include "boost_std_shared_shim.hpp"
#include "python_to_value.hpp"
// boost // boost
#include <boost/python.hpp> #include <boost/python.hpp>
@ -69,6 +70,15 @@ struct names_to_list
} }
}; };
namespace {
void set_variables(mapnik::query & q, boost::python::dict const& d)
{
mapnik::attributes vars = mapnik::dict2attr(d);
q.set_variables(vars);
}
}
void export_query() void export_query()
{ {
using namespace boost::python; using namespace boost::python;
@ -85,5 +95,6 @@ void export_query()
return_value_policy<copy_const_reference>()) ) return_value_policy<copy_const_reference>()) )
.add_property("property_names", make_function(&query::property_names, .add_property("property_names", make_function(&query::property_names,
return_value_policy<copy_const_reference>()) ) return_value_policy<copy_const_reference>()) )
.def("add_property_name", &query::add_property_name); .def("add_property_name", &query::add_property_name)
.def("set_variables",&set_variables);
} }

View file

@ -125,10 +125,10 @@ struct NodeWrap: formatting::node, wrapper<formatting::node>
} }
void apply(char_properties_ptr p, feature_impl const& feature, text_layout &output) const void apply(char_properties_ptr p, feature_impl const& feature, attributes const& vars, text_layout &output) const
{ {
python_block_auto_unblock b; python_block_auto_unblock b;
this->get_override("apply")(ptr(&p), ptr(&feature), ptr(&output)); this->get_override("apply")(ptr(&p), ptr(&feature), ptr(&vars), ptr(&output));
} }
virtual void add_expressions(expression_set &output) const virtual void add_expressions(expression_set &output) const
@ -163,85 +163,85 @@ struct TextNodeWrap: formatting::text_node, wrapper<formatting::text_node>
} }
virtual void apply(char_properties_ptr p, feature_impl const& feature, text_layout &output) const virtual void apply(char_properties_ptr p, feature_impl const& feature, attributes const& vars, text_layout &output) const
{ {
if(override o = this->get_override("apply")) if(override o = this->get_override("apply"))
{ {
python_block_auto_unblock b; python_block_auto_unblock b;
o(ptr(&p), ptr(&feature), ptr(&output)); o(ptr(&p), ptr(&feature), ptr(&vars), ptr(&output));
} }
else else
{ {
formatting::text_node::apply(p, feature, output); formatting::text_node::apply(p, feature, vars, output);
} }
} }
void default_apply(char_properties_ptr p, feature_impl const& feature, text_layout &output) const void default_apply(char_properties_ptr p, feature_impl const& feature, attributes const& vars, text_layout &output) const
{ {
formatting::text_node::apply(p, feature, output); formatting::text_node::apply(p, feature, vars, output);
} }
}; };
struct FormatNodeWrap: formatting::format_node, wrapper<formatting::format_node> struct FormatNodeWrap: formatting::format_node, wrapper<formatting::format_node>
{ {
virtual void apply(char_properties_ptr p, feature_impl const& feature, text_layout &output) const virtual void apply(char_properties_ptr p, feature_impl const& feature, attributes const& vars, text_layout &output) const
{ {
if(override o = this->get_override("apply")) if(override o = this->get_override("apply"))
{ {
python_block_auto_unblock b; python_block_auto_unblock b;
o(ptr(&p), ptr(&feature), ptr(&output)); o(ptr(&p), ptr(&feature), ptr(&vars), ptr(&output));
} }
else else
{ {
formatting::format_node::apply(p, feature, output); formatting::format_node::apply(p, feature, vars ,output);
} }
} }
void default_apply(char_properties_ptr p, feature_impl const& feature, text_layout &output) const void default_apply(char_properties_ptr p, feature_impl const& feature, attributes const& vars, text_layout &output) const
{ {
formatting::format_node::apply(p, feature, output); formatting::format_node::apply(p, feature, vars, output);
} }
}; };
struct ExprFormatWrap: formatting::expression_format, wrapper<formatting::expression_format> struct ExprFormatWrap: formatting::expression_format, wrapper<formatting::expression_format>
{ {
virtual void apply(char_properties_ptr p, feature_impl const& feature, text_layout &output) const virtual void apply(char_properties_ptr p, feature_impl const& feature, attributes const& vars, text_layout &output) const
{ {
if(override o = this->get_override("apply")) if(override o = this->get_override("apply"))
{ {
python_block_auto_unblock b; python_block_auto_unblock b;
o(ptr(&p), ptr(&feature), ptr(&output)); o(ptr(&p), ptr(&feature), ptr(&vars), ptr(&output));
} }
else else
{ {
formatting::expression_format::apply(p, feature, output); formatting::expression_format::apply(p, feature, vars, output);
} }
} }
void default_apply(char_properties_ptr p, feature_impl const& feature, text_layout &output) const void default_apply(char_properties_ptr p, feature_impl const& feature, attributes const& vars, text_layout &output) const
{ {
formatting::expression_format::apply(p, feature, output); formatting::expression_format::apply(p, feature, vars, output);
} }
}; };
struct LayoutNodeWrap: formatting::layout_node, wrapper<formatting::layout_node> struct LayoutNodeWrap: formatting::layout_node, wrapper<formatting::layout_node>
{ {
virtual void apply(char_properties_ptr p, feature_impl const& feature, text_layout &output) const virtual void apply(char_properties_ptr p, feature_impl const& feature, attributes const& vars, text_layout &output) const
{ {
if(override o = this->get_override("apply")) if(override o = this->get_override("apply"))
{ {
python_block_auto_unblock b; python_block_auto_unblock b;
o(ptr(&p), ptr(&feature), ptr(&output)); o(ptr(&p), ptr(&feature), ptr(&vars), ptr(&output));
} }
else else
{ {
formatting::layout_node::apply(p, feature, output); formatting::layout_node::apply(p, feature, vars, output);
} }
} }
void default_apply(char_properties_ptr p, feature_impl const& feature, text_layout &output) const void default_apply(char_properties_ptr p, feature_impl const& feature, attributes const& vars, text_layout &output) const
{ {
formatting::layout_node::apply(p, feature, output); formatting::layout_node::apply(p, feature, vars, output);
} }
}; };
@ -266,22 +266,22 @@ struct ListNodeWrap: formatting::list_node, wrapper<formatting::list_node>
/* TODO: Add constructor taking variable number of arguments. /* TODO: Add constructor taking variable number of arguments.
http://wiki.python.org/moin/boost.python/HowTo#A.22Raw.22_function */ http://wiki.python.org/moin/boost.python/HowTo#A.22Raw.22_function */
virtual void apply(char_properties_ptr p, feature_impl const& feature, text_layout &output) const virtual void apply(char_properties_ptr p, feature_impl const& feature, attributes const& vars, text_layout &output) const
{ {
if(override o = this->get_override("apply")) if(override o = this->get_override("apply"))
{ {
python_block_auto_unblock b; python_block_auto_unblock b;
o(ptr(&p), ptr(&feature), ptr(&output)); o(ptr(&p), ptr(&feature), ptr(&vars), ptr(&output));
} }
else else
{ {
formatting::list_node::apply(p, feature, output); formatting::list_node::apply(p, feature, vars, output);
} }
} }
void default_apply(char_properties_ptr p, feature_impl const& feature, text_layout &output) const void default_apply(char_properties_ptr p, feature_impl const& feature, attributes const& vars, text_layout &output) const
{ {
formatting::list_node::apply(p, feature, output); formatting::list_node::apply(p, feature, vars, output);
} }
inline void IndexError(){ inline void IndexError(){

View file

@ -0,0 +1,90 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2014 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_PYTHON_BINDING_PYTHON_TO_VALUE
#define MAPNIK_PYTHON_BINDING_PYTHON_TO_VALUE
// boost
#include <boost/python.hpp>
// mapnik
#include <mapnik/value.hpp>
#include <mapnik/attribute.hpp>
namespace mapnik {
static mapnik::attributes dict2attr(boost::python::dict const& d)
{
using namespace boost::python;
mapnik::attributes vars;
mapnik::transcoder tr_("utf8");
boost::python::list keys=d.keys();
for (int i=0; i < len(keys); ++i)
{
std::string key = extract<std::string>(keys[i]);
object obj = d[key];
if (PyUnicode_Check(obj.ptr()))
{
PyObject* temp = PyUnicode_AsUTF8String(obj.ptr());
if (temp)
{
#if PY_VERSION_HEX >= 0x03000000
char* c_str = PyBytes_AsString(temp);
#else
char* c_str = PyString_AsString(temp);
#endif
vars[key] = tr_.transcode(c_str);
Py_DecRef(temp);
}
continue;
}
extract<std::string> ex0(obj);
if (ex0.check())
{
vars[key] = tr_.transcode(ex0().c_str());
continue;
}
extract<mapnik::value_integer> ex2(obj);
if (ex2.check())
{
vars[key] = ex2();
continue;
}
extract<double> ex3(obj);
if (ex3.check())
{
vars[key] = ex3();
continue;
}
extract<mapnik::value_bool> ex1(obj);
if (ex1.check())
{
vars[key] = ex1();
continue;
}
}
return vars;
}
}
#endif // MAPNIK_PYTHON_BINDING_PYTHON_TO_VALUE

View file

@ -61,9 +61,9 @@ void set_gamma_method(T & ras_ptr, double gamma, gamma_method_enum method)
} }
template <typename Symbolizer, typename PathType, typename Feature> template <typename Symbolizer, typename PathType, typename Feature>
void set_join_caps(Symbolizer const& sym, PathType & stroke, Feature const& feature) void set_join_caps(Symbolizer const& sym, PathType & stroke, Feature const& feature, attributes const& vars)
{ {
line_join_enum join = get<line_join_enum>(sym, keys::stroke_linejoin, feature, MITER_JOIN); line_join_enum join = get<line_join_enum>(sym, keys::stroke_linejoin, feature, vars, MITER_JOIN);
switch (join) switch (join)
{ {
case MITER_JOIN: case MITER_JOIN:
@ -79,7 +79,7 @@ void set_join_caps(Symbolizer const& sym, PathType & stroke, Feature const& feat
stroke.generator().line_join(agg::bevel_join); stroke.generator().line_join(agg::bevel_join);
} }
line_cap_enum cap = get<line_cap_enum>(sym, keys::stroke_linecap, feature, BUTT_CAP); line_cap_enum cap = get<line_cap_enum>(sym, keys::stroke_linecap, feature, vars, BUTT_CAP);
switch (cap) switch (cap)
{ {
@ -96,9 +96,9 @@ void set_join_caps(Symbolizer const& sym, PathType & stroke, Feature const& feat
template <typename Symbolizer, typename Rasterizer, typename Feature> template <typename Symbolizer, typename Rasterizer, typename Feature>
void set_join_caps_aa(Symbolizer const& sym, Rasterizer & ras, Feature & feature) void set_join_caps_aa(Symbolizer const& sym, Rasterizer & ras, Feature & feature, attributes const& vars)
{ {
line_join_enum join = get<line_join_enum>(sym, keys::stroke_linejoin, feature, MITER_JOIN); line_join_enum join = get<line_join_enum>(sym, keys::stroke_linejoin, feature, vars, MITER_JOIN);
switch (join) switch (join)
{ {
case MITER_JOIN: case MITER_JOIN:
@ -114,7 +114,7 @@ void set_join_caps_aa(Symbolizer const& sym, Rasterizer & ras, Feature & feature
ras.line_join(agg::outline_no_join); ras.line_join(agg::outline_no_join);
} }
line_cap_enum cap = get<line_cap_enum>(sym, keys::stroke_linecap, feature, BUTT_CAP); line_cap_enum cap = get<line_cap_enum>(sym, keys::stroke_linecap, feature, vars, BUTT_CAP);
switch (cap) switch (cap)
{ {

View file

@ -73,7 +73,7 @@ public:
agg_renderer(Map const &m, buffer_type & pixmap, std::shared_ptr<detector_type> detector, agg_renderer(Map const &m, buffer_type & pixmap, std::shared_ptr<detector_type> 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 // pass in mapnik::request object to provide the mutable things per render
agg_renderer(Map const& m, request const& req, buffer_type & pixmap, double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0); agg_renderer(Map const& m, request const& req, attributes const& vars, buffer_type & 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);
@ -142,6 +142,11 @@ public:
return common_.scale_factor_; return common_.scale_factor_;
} }
inline attributes const& variables() const
{
return common_.vars_;
}
inline box2d<double> clipping_extent() const inline box2d<double> clipping_extent() const
{ {
if (common_.t_.offset() > 0) if (common_.t_.offset() > 0)

View file

@ -26,9 +26,11 @@
// mapnik // mapnik
#include <mapnik/value_types.hpp> #include <mapnik/value_types.hpp>
#include <mapnik/geometry.hpp> #include <mapnik/geometry.hpp>
#include <mapnik/value.hpp>
// stl // stl
#include <string> #include <string>
#include <unordered_map>
namespace mapnik { namespace mapnik {
@ -78,6 +80,8 @@ struct global_attribute
} }
}; };
typedef std::unordered_map<std::string, value> attributes;
} }
#endif // MAPNIK_ATTRIBUTE_HPP #endif // MAPNIK_ATTRIBUTE_HPP

View file

@ -58,17 +58,20 @@ class MAPNIK_DECL cairo_renderer_base : private mapnik::noncopyable
protected: protected:
cairo_renderer_base(Map const& m, cairo_renderer_base(Map const& m,
cairo_ptr const& cairo, cairo_ptr const& cairo,
attributes const& vars,
double scale_factor=1.0, double scale_factor=1.0,
unsigned offset_x=0, unsigned offset_x=0,
unsigned offset_y=0); unsigned offset_y=0);
cairo_renderer_base(Map const& m, cairo_renderer_base(Map const& m,
request const& req, request const& req,
cairo_ptr const& cairo, cairo_ptr const& cairo,
attributes const& vars,
double scale_factor=1.0, double scale_factor=1.0,
unsigned offset_x=0, unsigned offset_x=0,
unsigned offset_y=0); unsigned offset_y=0);
cairo_renderer_base(Map const& m, cairo_renderer_base(Map const& m,
cairo_ptr const& cairo, cairo_ptr const& cairo,
attributes const& vars,
std::shared_ptr<label_collision_detector4> detector, std::shared_ptr<label_collision_detector4> detector,
double scale_factor=1.0, double scale_factor=1.0,
unsigned offset_x=0, unsigned offset_x=0,
@ -138,6 +141,11 @@ public:
return common_.scale_factor_; return common_.scale_factor_;
} }
inline attributes const& variables() const
{
return common_.vars_;
}
void render_marker(pixel_position const& pos, void render_marker(pixel_position const& pos,
marker const& marker, marker const& marker,
agg::trans_affine const& mtx, agg::trans_affine const& mtx,
@ -165,6 +173,7 @@ public:
unsigned offset_y=0); unsigned offset_y=0);
cairo_renderer(Map const& m, cairo_renderer(Map const& m,
request const& req, request const& req,
attributes const& vars,
T const& obj, T const& obj,
double scale_factor=1.0, double scale_factor=1.0,
unsigned offset_x=0, unsigned offset_x=0,

View file

@ -39,14 +39,16 @@
namespace mapnik namespace mapnik
{ {
template <typename T0, typename T1> template <typename T0, typename T1, typename T2>
struct evaluate : boost::static_visitor<T1> struct evaluate : boost::static_visitor<T1>
{ {
typedef T0 feature_type; typedef T0 feature_type;
typedef T1 value_type; typedef T1 value_type;
typedef T2 variable_type;
explicit evaluate(feature_type const& f) explicit evaluate(feature_type const& f, variable_type const& v)
: feature_(f) {} : feature_(f),
vars_(v) {}
value_integer operator() (value_integer val) const value_integer operator() (value_integer val) const
{ {
@ -80,7 +82,12 @@ struct evaluate : boost::static_visitor<T1>
value_type operator() (global_attribute const& attr) const value_type operator() (global_attribute const& attr) const
{ {
return value_type();// shouldn't get here auto itr = vars_.find(attr.name);
if (itr != vars_.end())
{
return itr->second;
}
return value_type();// throw?
} }
value_type operator() (geometry_type_attribute const& geom) const value_type operator() (geometry_type_attribute const& geom) const
@ -144,6 +151,7 @@ struct evaluate : boost::static_visitor<T1>
} }
feature_type const& feature_; feature_type const& feature_;
variable_type const& vars_;
}; };
} }

View file

@ -471,6 +471,7 @@ void feature_style_processor<Processor>::prepare_layer(layer_rendering_material
height/qh); height/qh);
query q(layer_ext,res,scale_denom,extent); query q(layer_ext,res,scale_denom,extent);
q.set_variables(p.variables());
if (p.attribute_collection_policy() == COLLECT_ALL) if (p.attribute_collection_policy() == COLLECT_ALL)
{ {
@ -643,6 +644,7 @@ void feature_style_processor<Processor>::render_style(
p.end_style_processing(*style); p.end_style_processing(*style);
return; return;
} }
mapnik::attributes vars = p.variables();
feature_ptr feature; feature_ptr feature;
bool was_painted = false; bool was_painted = false;
while ((feature = features->next())) while ((feature = features->next()))
@ -652,7 +654,7 @@ void feature_style_processor<Processor>::render_style(
for (rule const* r : rc.get_if_rules() ) for (rule const* r : rc.get_if_rules() )
{ {
expression_ptr const& expr = r->get_filter(); expression_ptr const& expr = r->get_filter();
value_type result = boost::apply_visitor(evaluate<feature_impl,value_type>(*feature),*expr); value_type result = boost::apply_visitor(evaluate<feature_impl,value_type,attributes>(*feature,vars),*expr);
if (result.to_bool()) if (result.to_bool())
{ {
was_painted = true; was_painted = true;

View file

@ -55,6 +55,7 @@ struct raster_markers_rasterizer_dispatch_grid
Detector & detector, Detector & detector,
double scale_factor, double scale_factor,
mapnik::feature_impl & feature, mapnik::feature_impl & feature,
attributes const& vars,
PixMapType & pixmap) PixMapType & pixmap)
: buf_(render_buffer), : buf_(render_buffer),
pixf_(buf_), pixf_(buf_),
@ -66,29 +67,19 @@ struct raster_markers_rasterizer_dispatch_grid
detector_(detector), detector_(detector),
scale_factor_(scale_factor), scale_factor_(scale_factor),
feature_(feature), feature_(feature),
vars_(vars),
pixmap_(pixmap), pixmap_(pixmap),
placed_(false) placed_(false)
{
// TODO - support basic binary operators
//pixf_.comp_op(static_cast<agg::comp_op_e>(sym_.comp_op()));
}
raster_markers_rasterizer_dispatch_grid(raster_markers_rasterizer_dispatch_grid &&d)
: buf_(d.buf_), pixf_(d.pixf_), renb_(d.renb_), ras_(d.ras_), src_(d.src_),
marker_trans_(d.marker_trans_), sym_(d.sym_), detector_(d.detector_),
scale_factor_(d.scale_factor_), feature_(d.feature_), pixmap_(d.pixmap_),
placed_(d.placed_)
{ {
} }
template <typename T> template <typename T>
void add_path(T & path) void add_path(T & path)
{ {
marker_placement_enum placement_method = get<marker_placement_enum>(sym_, keys::markers_placement_type, MARKER_POINT_PLACEMENT); agg::scanline_bin sl_;
bool ignore_placement = get<bool>(sym_, keys::ignore_placement, false); marker_placement_enum placement_method = get<marker_placement_enum>(sym_, keys::markers_placement_type, feature_, vars_, MARKER_POINT_PLACEMENT);
bool allow_overlap = get<bool>(sym_, keys::allow_overlap, false); bool ignore_placement = get<bool>(sym_, keys::ignore_placement, feature_, vars_, false);
double spacing = get<double>(sym_, keys::spacing, 100.0); bool allow_overlap = get<bool>(sym_, keys::allow_overlap, feature_, vars_, false);
double max_error = get<double>(sym_, keys::max_error, 0.2);
box2d<double> bbox_(0,0, src_.width(),src_.height()); box2d<double> bbox_(0,0, src_.width(),src_.height());
if (placement_method != MARKER_LINE_PLACEMENT || if (placement_method != MARKER_LINE_PLACEMENT ||
@ -99,17 +90,23 @@ struct raster_markers_rasterizer_dispatch_grid
if (path.type() == geometry_type::types::LineString) if (path.type() == geometry_type::types::LineString)
{ {
if (!label::middle_point(path, x, y)) if (!label::middle_point(path, x, y))
{
return; return;
}
} }
else if (placement_method == MARKER_INTERIOR_PLACEMENT) else if (placement_method == MARKER_INTERIOR_PLACEMENT)
{ {
if (!label::interior_position(path, x, y)) if (!label::interior_position(path, x, y))
{
return; return;
}
} }
else else
{ {
if (!label::centroid(path, x, y)) if (!label::centroid(path, x, y))
{
return; return;
}
} }
agg::trans_affine matrix = marker_trans_; agg::trans_affine matrix = marker_trans_;
matrix.translate(x,y); matrix.translate(x,y);
@ -131,6 +128,8 @@ struct raster_markers_rasterizer_dispatch_grid
} }
else else
{ {
double spacing = get<double>(sym_, keys::spacing, feature_, vars_, 100.0);
double max_error = get<double>(sym_, keys::max_error, feature_, vars_, 0.2);
markers_placement<T, label_collision_detector4> placement(path, bbox_, marker_trans_, detector_, markers_placement<T, label_collision_detector4> placement(path, bbox_, marker_trans_, detector_,
spacing * scale_factor_, spacing * scale_factor_,
max_error, max_error,
@ -153,6 +152,7 @@ struct raster_markers_rasterizer_dispatch_grid
void render_raster_marker(agg::trans_affine const& marker_tr) void render_raster_marker(agg::trans_affine const& marker_tr)
{ {
agg::scanline_bin sl_;
double width = src_.width(); double width = src_.width();
double height = src_.height(); double height = src_.height();
double p[8]; double p[8];
@ -174,7 +174,6 @@ struct raster_markers_rasterizer_dispatch_grid
} }
private: private:
agg::scanline_bin sl_;
BufferType & buf_; BufferType & buf_;
PixFmt pixf_; PixFmt pixf_;
RendererBase renb_; RendererBase renb_;
@ -185,6 +184,7 @@ private:
Detector & detector_; Detector & detector_;
double scale_factor_; double scale_factor_;
mapnik::feature_impl & feature_; mapnik::feature_impl & feature_;
attributes const& vars_;
PixMapType & pixmap_; PixMapType & pixmap_;
bool placed_; bool placed_;
}; };
@ -208,6 +208,7 @@ struct vector_markers_rasterizer_dispatch_grid
Detector & detector, Detector & detector,
double scale_factor, double scale_factor,
mapnik::feature_impl & feature, mapnik::feature_impl & feature,
attributes const& vars,
PixMapType & pixmap) PixMapType & pixmap)
: buf_(render_buffer), : buf_(render_buffer),
pixf_(buf_), pixf_(buf_),
@ -220,30 +221,20 @@ struct vector_markers_rasterizer_dispatch_grid
detector_(detector), detector_(detector),
scale_factor_(scale_factor), scale_factor_(scale_factor),
feature_(feature), feature_(feature),
vars_(vars),
pixmap_(pixmap), pixmap_(pixmap),
placed_(false) placed_(false)
{
// TODO
//pixf_.comp_op(static_cast<agg::comp_op_e>(sym_.comp_op()));
}
vector_markers_rasterizer_dispatch_grid(vector_markers_rasterizer_dispatch_grid &&d)
: buf_(d.buf_), pixf_(d.pixf_), svg_renderer_(std::move(d.svg_renderer_)), ras_(d.ras_),
bbox_(d.bbox_), marker_trans_(d.marker_trans_), sym_(d.sym_), detector_(d.detector_),
scale_factor_(d.scale_factor_), feature_(d.feature_), pixmap_(d.pixmap_),
placed_(d.placed_)
{ {
} }
template <typename T> template <typename T>
void add_path(T & path) void add_path(T & path)
{ {
marker_placement_enum placement_method = get<marker_placement_enum>(sym_, keys::markers_placement_type, MARKER_POINT_PLACEMENT); agg::scanline_bin sl_;
bool ignore_placement = get<bool>(sym_, keys::ignore_placement, false); marker_placement_enum placement_method = get<marker_placement_enum>(sym_, keys::markers_placement_type, feature_, vars_, MARKER_POINT_PLACEMENT);
double spacing = get<double>(sym_, keys::spacing, 100.0); bool ignore_placement = get<bool>(sym_, keys::ignore_placement, feature_, vars_, false);
double max_error = get<double>(sym_, keys::max_error, 0.2); double opacity = get<double>(sym_,keys::opacity, feature_, vars_, 1.0);
double opacity = get<double>(sym_,keys::opacity, 1.0); bool allow_overlap = get<bool>(sym_, keys::allow_overlap, feature_, vars_, false);
bool allow_overlap = get<bool>(sym_, keys::allow_overlap, false);
if (placement_method != MARKER_LINE_PLACEMENT || if (placement_method != MARKER_LINE_PLACEMENT ||
path.type() == geometry_type::types::Point) path.type() == geometry_type::types::Point)
@ -253,17 +244,23 @@ struct vector_markers_rasterizer_dispatch_grid
if (path.type() == geometry_type::types::LineString) if (path.type() == geometry_type::types::LineString)
{ {
if (!label::middle_point(path, x, y)) if (!label::middle_point(path, x, y))
{
return; return;
}
} }
else if (placement_method == MARKER_INTERIOR_PLACEMENT) else if (placement_method == MARKER_INTERIOR_PLACEMENT)
{ {
if (!label::interior_position(path, x, y)) if (!label::interior_position(path, x, y))
{
return; return;
}
} }
else else
{ {
if (!label::centroid(path, x, y)) if (!label::centroid(path, x, y))
{
return; return;
}
} }
agg::trans_affine matrix = marker_trans_; agg::trans_affine matrix = marker_trans_;
matrix.translate(x,y); matrix.translate(x,y);
@ -285,6 +282,8 @@ struct vector_markers_rasterizer_dispatch_grid
} }
else else
{ {
double spacing = get<double>(sym_, keys::spacing, feature_, vars_, 100.0);
double max_error = get<double>(sym_, keys::max_error, feature_, vars_, 0.2);
markers_placement<T, Detector> placement(path, bbox_, marker_trans_, detector_, markers_placement<T, Detector> placement(path, bbox_, marker_trans_, detector_,
spacing * scale_factor_, spacing * scale_factor_,
max_error, max_error,
@ -305,7 +304,6 @@ struct vector_markers_rasterizer_dispatch_grid
} }
} }
private: private:
agg::scanline_bin sl_;
BufferType & buf_; BufferType & buf_;
pixfmt_type pixf_; pixfmt_type pixf_;
renderer_base renb_; renderer_base renb_;
@ -317,10 +315,10 @@ private:
Detector & detector_; Detector & detector_;
double scale_factor_; double scale_factor_;
mapnik::feature_impl & feature_; mapnik::feature_impl & feature_;
attributes const& vars_;
PixMapType & pixmap_; PixMapType & pixmap_;
bool placed_; bool placed_;
}; };
} }
#endif #endif

View file

@ -68,7 +68,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(Map const& m, request const& req, attributes const& vars, 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);
@ -131,6 +131,11 @@ public:
return common_.scale_factor_; return common_.scale_factor_;
} }
inline attributes const& variables() const
{
return common_.vars_;
}
private: private:
buffer_type & pixmap_; buffer_type & pixmap_;
const std::unique_ptr<grid_rasterizer> ras_ptr; const std::unique_ptr<grid_rasterizer> ras_ptr;

View file

@ -55,6 +55,7 @@ public:
group_symbolizer_helper(group_symbolizer const& sym, group_symbolizer_helper(group_symbolizer const& sym,
feature_impl const& feature, feature_impl const& feature,
attributes const& vars,
proj_transform const& prj_trans, proj_transform const& prj_trans,
unsigned width, unsigned width,
unsigned height, unsigned height,

View file

@ -34,6 +34,7 @@
#include <mapnik/marker.hpp> // for svg_storage_type #include <mapnik/marker.hpp> // for svg_storage_type
#include <mapnik/svg/svg_storage.hpp> #include <mapnik/svg/svg_storage.hpp>
#include <mapnik/markers_placement.hpp> #include <mapnik/markers_placement.hpp>
#include <mapnik/vertex_converters.hpp>
// agg // agg
#include "agg_ellipse.h" #include "agg_ellipse.h"
@ -74,6 +75,8 @@ struct vector_markers_rasterizer_dispatch
agg::trans_affine const& marker_trans, agg::trans_affine const& marker_trans,
markers_symbolizer const& sym, markers_symbolizer const& sym,
Detector & detector, Detector & detector,
feature_impl & feature,
attributes const& vars,
double scale_factor, double scale_factor,
bool snap_to_pixels) bool snap_to_pixels)
: buf_(render_buffer), : buf_(render_buffer),
@ -85,26 +88,22 @@ struct vector_markers_rasterizer_dispatch
marker_trans_(marker_trans), marker_trans_(marker_trans),
sym_(sym), sym_(sym),
detector_(detector), detector_(detector),
feature_(feature),
vars_(vars),
scale_factor_(scale_factor), scale_factor_(scale_factor),
snap_to_pixels_(snap_to_pixels) snap_to_pixels_(snap_to_pixels)
{ {
pixf_.comp_op(get<agg::comp_op_e>(sym_, keys::comp_op, agg::comp_op_src_over)); pixf_.comp_op(get<agg::comp_op_e>(sym_, keys::comp_op, feature_, vars_, agg::comp_op_src_over));
}
vector_markers_rasterizer_dispatch(vector_markers_rasterizer_dispatch &&d)
: buf_(d.buf_), pixf_(d.pixf_), svg_renderer_(std::move(d.svg_renderer_)), ras_(d.ras_),
bbox_(d.bbox_), marker_trans_(d.marker_trans_), sym_(d.sym_), detector_(d.detector_),
scale_factor_(d.scale_factor_), snap_to_pixels_(d.snap_to_pixels_)
{
} }
template <typename T> template <typename T>
void add_path(T & path) void add_path(T & path)
{ {
marker_placement_enum placement_method = get<marker_placement_enum>(sym_, keys::markers_placement_type, MARKER_POINT_PLACEMENT); agg::scanline_u8 sl_;
bool ignore_placement = get<bool>(sym_, keys::ignore_placement, false); marker_placement_enum placement_method = get<marker_placement_enum>(sym_, keys::markers_placement_type, feature_, vars_, MARKER_POINT_PLACEMENT);
bool allow_overlap = get<bool>(sym_, keys::allow_overlap, false); bool ignore_placement = get<bool>(sym_, keys::ignore_placement, feature_, vars_, false);
double opacity = get<double>(sym_,keys::opacity, 1.0); bool allow_overlap = get<bool>(sym_, keys::allow_overlap, feature_, vars_, false);
double opacity = get<double>(sym_,keys::opacity, feature_, vars_, 1.0);
if (placement_method != MARKER_LINE_PLACEMENT || if (placement_method != MARKER_LINE_PLACEMENT ||
path.type() == mapnik::geometry_type::types::Point) path.type() == mapnik::geometry_type::types::Point)
@ -114,17 +113,23 @@ struct vector_markers_rasterizer_dispatch
if (path.type() == mapnik::geometry_type::types::LineString) if (path.type() == mapnik::geometry_type::types::LineString)
{ {
if (!label::middle_point(path, x, y)) if (!label::middle_point(path, x, y))
{
return; return;
}
} }
else if (placement_method == MARKER_INTERIOR_PLACEMENT) else if (placement_method == MARKER_INTERIOR_PLACEMENT)
{ {
if (!label::interior_position(path, x, y)) if (!label::interior_position(path, x, y))
{
return; return;
}
} }
else else
{ {
if (!label::centroid(path, x, y)) if (!label::centroid(path, x, y))
{
return; return;
}
} }
agg::trans_affine matrix = marker_trans_; agg::trans_affine matrix = marker_trans_;
matrix.translate(x,y); matrix.translate(x,y);
@ -149,8 +154,8 @@ struct vector_markers_rasterizer_dispatch
} }
else else
{ {
double spacing = get<double>(sym_, keys::spacing, 100.0); double spacing = get<double>(sym_, keys::spacing, feature_, vars_, 100.0);
double max_error = get<double>(sym_, keys::max_error, 0.2); double max_error = get<double>(sym_, keys::max_error, feature_, vars_, 0.2);
markers_placement<T, Detector> placement(path, bbox_, marker_trans_, detector_, markers_placement<T, Detector> placement(path, bbox_, marker_trans_, detector_,
spacing * scale_factor_, spacing * scale_factor_,
max_error, max_error,
@ -168,7 +173,6 @@ struct vector_markers_rasterizer_dispatch
} }
} }
private: private:
agg::scanline_u8 sl_;
BufferType & buf_; BufferType & buf_;
pixfmt_type pixf_; pixfmt_type pixf_;
renderer_base renb_; renderer_base renb_;
@ -178,6 +182,8 @@ private:
agg::trans_affine const& marker_trans_; agg::trans_affine const& marker_trans_;
markers_symbolizer const& sym_; markers_symbolizer const& sym_;
Detector & detector_; Detector & detector_;
feature_impl & feature_;
attributes const& vars_;
double scale_factor_; double scale_factor_;
bool snap_to_pixels_; bool snap_to_pixels_;
}; };
@ -198,6 +204,8 @@ struct raster_markers_rasterizer_dispatch
agg::trans_affine const& marker_trans, agg::trans_affine const& marker_trans,
markers_symbolizer const& sym, markers_symbolizer const& sym,
Detector & detector, Detector & detector,
feature_impl & feature,
attributes const& vars,
double scale_factor, double scale_factor,
bool snap_to_pixels) bool snap_to_pixels)
: buf_(render_buffer), : buf_(render_buffer),
@ -208,27 +216,22 @@ struct raster_markers_rasterizer_dispatch
marker_trans_(marker_trans), marker_trans_(marker_trans),
sym_(sym), sym_(sym),
detector_(detector), detector_(detector),
feature_(feature),
vars_(vars),
scale_factor_(scale_factor), scale_factor_(scale_factor),
snap_to_pixels_(snap_to_pixels) snap_to_pixels_(snap_to_pixels)
{ {
pixf_.comp_op(get<agg::comp_op_e>(sym_, keys::comp_op, agg::comp_op_src_over)); pixf_.comp_op(get<agg::comp_op_e>(sym_, keys::comp_op, feature_, vars_, agg::comp_op_src_over));
}
raster_markers_rasterizer_dispatch(raster_markers_rasterizer_dispatch &&d)
: buf_(d.buf_), pixf_(d.pixf_), renb_(d.renb_), ras_(d.ras_), src_(d.src_),
marker_trans_(d.marker_trans_), sym_(d.sym_), detector_(d.detector_),
scale_factor_(d.scale_factor_), snap_to_pixels_(d.snap_to_pixels_)
{
} }
template <typename T> template <typename T>
void add_path(T & path) void add_path(T & path)
{ {
marker_placement_enum placement_method = get<marker_placement_enum>(sym_, keys::markers_placement_type, MARKER_POINT_PLACEMENT); marker_placement_enum placement_method = get<marker_placement_enum>(sym_, keys::markers_placement_type, feature_, vars_, MARKER_POINT_PLACEMENT);
bool allow_overlap = get<bool>(sym_, keys::allow_overlap, false); bool allow_overlap = get<bool>(sym_, keys::allow_overlap, feature_, vars_, false);
box2d<double> bbox_(0,0, src_.width(),src_.height()); box2d<double> bbox_(0,0, src_.width(),src_.height());
double opacity = get<double>(sym_, keys::opacity, 1.0); double opacity = get<double>(sym_, keys::opacity, feature_, vars_, 1.0);
bool ignore_placement = get<bool>(sym_, keys::ignore_placement, false); bool ignore_placement = get<bool>(sym_, keys::ignore_placement, feature_, vars_, false);
if (placement_method != MARKER_LINE_PLACEMENT || if (placement_method != MARKER_LINE_PLACEMENT ||
path.type() == mapnik::geometry_type::types::Point) path.type() == mapnik::geometry_type::types::Point)
@ -238,17 +241,23 @@ struct raster_markers_rasterizer_dispatch
if (path.type() == mapnik::geometry_type::types::LineString) if (path.type() == mapnik::geometry_type::types::LineString)
{ {
if (!label::middle_point(path, x, y)) if (!label::middle_point(path, x, y))
{
return; return;
}
} }
else if (placement_method == MARKER_INTERIOR_PLACEMENT) else if (placement_method == MARKER_INTERIOR_PLACEMENT)
{ {
if (!label::interior_position(path, x, y)) if (!label::interior_position(path, x, y))
{
return; return;
}
} }
else else
{ {
if (!label::centroid(path, x, y)) if (!label::centroid(path, x, y))
{
return; return;
}
} }
agg::trans_affine matrix = marker_trans_; agg::trans_affine matrix = marker_trans_;
matrix.translate(x,y); matrix.translate(x,y);
@ -266,8 +275,8 @@ struct raster_markers_rasterizer_dispatch
} }
else else
{ {
double spacing = get<double>(sym_, keys::spacing, 100.0); double spacing = get<double>(sym_, keys::spacing, feature_, vars_, 100.0);
double max_error = get<double>(sym_, keys::max_error, 0.2); double max_error = get<double>(sym_, keys::max_error, feature_, vars_, 0.2);
markers_placement<T, label_collision_detector4> placement(path, bbox_, marker_trans_, detector_, markers_placement<T, label_collision_detector4> placement(path, bbox_, marker_trans_, detector_,
spacing * scale_factor_, spacing * scale_factor_,
max_error, max_error,
@ -287,6 +296,7 @@ struct raster_markers_rasterizer_dispatch
double opacity) double opacity)
{ {
typedef agg::pixfmt_rgba32_pre pixfmt_pre; typedef agg::pixfmt_rgba32_pre pixfmt_pre;
agg::scanline_u8 sl_;
double width = src_.width(); double width = src_.width();
double height = src_.height(); double height = src_.height();
if (std::fabs(1.0 - scale_factor_) < 0.001 if (std::fabs(1.0 - scale_factor_) < 0.001
@ -349,7 +359,6 @@ struct raster_markers_rasterizer_dispatch
} }
private: private:
agg::scanline_u8 sl_;
BufferType & buf_; BufferType & buf_;
pixfmt_comp_type pixf_; pixfmt_comp_type pixf_;
renderer_base renb_; renderer_base renb_;
@ -358,13 +367,15 @@ private:
agg::trans_affine const& marker_trans_; agg::trans_affine const& marker_trans_;
markers_symbolizer const& sym_; markers_symbolizer const& sym_;
Detector & detector_; Detector & detector_;
feature_impl & feature_;
attributes const& vars_;
double scale_factor_; double scale_factor_;
bool snap_to_pixels_; bool snap_to_pixels_;
}; };
template <typename T> template <typename T>
void build_ellipse(T const& sym, mapnik::feature_impl const& feature, svg_storage_type & marker_ellipse, svg::svg_path_adapter & svg_path) void build_ellipse(T const& sym, mapnik::feature_impl & feature, attributes const& vars, svg_storage_type & marker_ellipse, svg::svg_path_adapter & svg_path)
{ {
auto width_expr = get<expression_ptr>(sym, keys::width); auto width_expr = get<expression_ptr>(sym, keys::width);
auto height_expr = get<expression_ptr>(sym, keys::height); auto height_expr = get<expression_ptr>(sym, keys::height);
@ -372,17 +383,17 @@ void build_ellipse(T const& sym, mapnik::feature_impl const& feature, svg_storag
double height = 0; double height = 0;
if (width_expr && height_expr) if (width_expr && height_expr)
{ {
width = boost::apply_visitor(evaluate<feature_impl,value_type>(feature), *width_expr).to_double(); width = boost::apply_visitor(evaluate<feature_impl,value_type,attributes>(feature,vars), *width_expr).to_double();
height = boost::apply_visitor(evaluate<feature_impl,value_type>(feature), *height_expr).to_double(); height = boost::apply_visitor(evaluate<feature_impl,value_type,attributes>(feature,vars), *height_expr).to_double();
} }
else if (width_expr) else if (width_expr)
{ {
width = boost::apply_visitor(evaluate<feature_impl,value_type>(feature), *width_expr).to_double(); width = boost::apply_visitor(evaluate<feature_impl,value_type,attributes>(feature,vars), *width_expr).to_double();
height = width; height = width;
} }
else if (height_expr) else if (height_expr)
{ {
height = boost::apply_visitor(evaluate<feature_impl,value_type>(feature), *height_expr).to_double(); height = boost::apply_visitor(evaluate<feature_impl,value_type,attributes>(feature,vars), *height_expr).to_double();
width = height; width = height;
} }
svg::svg_converter_type styled_svg(svg_path, marker_ellipse.attributes()); svg::svg_converter_type styled_svg(svg_path, marker_ellipse.attributes());
@ -400,13 +411,16 @@ void build_ellipse(T const& sym, mapnik::feature_impl const& feature, svg_storag
} }
template <typename Attr> template <typename Attr>
bool push_explicit_style(Attr const& src, Attr & dst, markers_symbolizer const& sym) bool push_explicit_style(Attr const& src, Attr & dst,
markers_symbolizer const& sym,
feature_impl & feature,
attributes const& vars)
{ {
auto fill_color = get_optional<color>(sym, keys::fill); auto fill_color = get_optional<color>(sym, keys::fill, feature, vars);
auto fill_opacity = get_optional<double>(sym, keys::fill_opacity); auto fill_opacity = get_optional<double>(sym, keys::fill_opacity, feature, vars);
auto stroke_color = get_optional<color>(sym, keys::stroke); auto stroke_color = get_optional<color>(sym, keys::stroke, feature, vars);
auto stroke_width = get_optional<double>(sym, keys::stroke_width); auto stroke_width = get_optional<double>(sym, keys::stroke_width, feature, vars);
auto stroke_opacity = get_optional<double>(sym, keys::stroke_opacity); auto stroke_opacity = get_optional<double>(sym, keys::stroke_opacity, feature, vars);
if (fill_color || if (fill_color ||
fill_opacity || fill_opacity ||
stroke_color || stroke_color ||
@ -463,7 +477,8 @@ template <typename T>
void setup_transform_scaling(agg::trans_affine & tr, void setup_transform_scaling(agg::trans_affine & tr,
double svg_width, double svg_width,
double svg_height, double svg_height,
mapnik::feature_impl const& feature, mapnik::feature_impl & feature,
attributes const& vars,
T const& sym) T const& sym)
{ {
double width = 0; double width = 0;
@ -471,11 +486,11 @@ void setup_transform_scaling(agg::trans_affine & tr,
expression_ptr width_expr = get<expression_ptr>(sym, keys::width); expression_ptr width_expr = get<expression_ptr>(sym, keys::width);
if (width_expr) if (width_expr)
width = boost::apply_visitor(evaluate<feature_impl,value_type>(feature), *width_expr).to_double(); width = boost::apply_visitor(evaluate<feature_impl,value_type,attributes>(feature,vars), *width_expr).to_double();
expression_ptr height_expr = get<expression_ptr>(sym, keys::height); expression_ptr height_expr = get<expression_ptr>(sym, keys::height);
if (height_expr) if (height_expr)
height = boost::apply_visitor(evaluate<feature_impl,value_type>(feature), *height_expr).to_double(); height = boost::apply_visitor(evaluate<feature_impl,value_type,attributes>(feature,vars), *height_expr).to_double();
if (width > 0 && height > 0) if (width > 0 && height > 0)
{ {
@ -497,7 +512,7 @@ void setup_transform_scaling(agg::trans_affine & tr,
// Apply markers to a feature with multiple geometries // Apply markers to a feature with multiple geometries
template <typename Converter> template <typename Converter>
void apply_markers_multi(feature_impl & feature, Converter& converter, markers_symbolizer const& sym) void apply_markers_multi(feature_impl & feature, attributes const& vars, Converter& converter, markers_symbolizer const& sym)
{ {
std::size_t geom_count = feature.paths().size(); std::size_t geom_count = feature.paths().size();
if (geom_count == 1) if (geom_count == 1)
@ -506,8 +521,8 @@ void apply_markers_multi(feature_impl & feature, Converter& converter, markers_s
} }
else if (geom_count > 1) else if (geom_count > 1)
{ {
marker_multi_policy_enum multi_policy = get<marker_multi_policy_enum>(sym, keys::markers_multipolicy, MARKER_EACH_MULTI); marker_multi_policy_enum multi_policy = get<marker_multi_policy_enum>(sym, keys::markers_multipolicy, feature, vars, MARKER_EACH_MULTI);
marker_placement_enum placement = get<marker_placement_enum>(sym, keys::markers_placement_type, MARKER_POINT_PLACEMENT); marker_placement_enum placement = get<marker_placement_enum>(sym, keys::markers_placement_type, feature, vars, MARKER_POINT_PLACEMENT);
if (placement == MARKER_POINT_PLACEMENT && if (placement == MARKER_POINT_PLACEMENT &&
multi_policy == MARKER_WHOLE_MULTI) multi_policy == MARKER_WHOLE_MULTI)
{ {
@ -551,7 +566,7 @@ void apply_markers_multi(feature_impl & feature, Converter& converter, markers_s
} }
for (geometry_type & path : feature.paths()) for (geometry_type & path : feature.paths())
{ {
converter.apply(path); converter.apply(path);
} }
} }
} }

View file

@ -25,6 +25,7 @@
//mapnik //mapnik
#include <mapnik/box2d.hpp> #include <mapnik/box2d.hpp>
#include <mapnik/attribute.hpp>
// boost // boost
#include <boost/tuple/tuple.hpp> #include <boost/tuple/tuple.hpp>
@ -49,7 +50,8 @@ public:
scale_denominator_(scale_denominator), scale_denominator_(scale_denominator),
filter_factor_(1.0), filter_factor_(1.0),
unbuffered_bbox_(unbuffered_bbox), unbuffered_bbox_(unbuffered_bbox),
names_() names_(),
vars_()
{} {}
query(box2d<double> const& bbox, query(box2d<double> const& bbox,
@ -60,7 +62,8 @@ public:
scale_denominator_(scale_denominator), scale_denominator_(scale_denominator),
filter_factor_(1.0), filter_factor_(1.0),
unbuffered_bbox_(bbox), unbuffered_bbox_(bbox),
names_() names_(),
vars_()
{} {}
query(box2d<double> const& bbox) query(box2d<double> const& bbox)
@ -69,7 +72,8 @@ public:
scale_denominator_(1.0), scale_denominator_(1.0),
filter_factor_(1.0), filter_factor_(1.0),
unbuffered_bbox_(bbox), unbuffered_bbox_(bbox),
names_() names_(),
vars_()
{} {}
query(query const& other) query(query const& other)
@ -78,7 +82,8 @@ public:
scale_denominator_(other.scale_denominator_), scale_denominator_(other.scale_denominator_),
filter_factor_(other.filter_factor_), filter_factor_(other.filter_factor_),
unbuffered_bbox_(other.unbuffered_bbox_), unbuffered_bbox_(other.unbuffered_bbox_),
names_(other.names_) names_(other.names_),
vars_(other.vars_)
{} {}
query& operator=(query const& other) query& operator=(query const& other)
@ -90,6 +95,7 @@ public:
filter_factor_=other.filter_factor_; filter_factor_=other.filter_factor_;
unbuffered_bbox_=other.unbuffered_bbox_; unbuffered_bbox_=other.unbuffered_bbox_;
names_=other.names_; names_=other.names_;
vars_=other.vars_;
return *this; return *this;
} }
@ -143,6 +149,16 @@ public:
return names_; return names_;
} }
void set_variables(attributes const& vars)
{
vars_ = vars;
}
attributes const& variables() const
{
return vars_;
}
private: private:
box2d<double> bbox_; box2d<double> bbox_;
resolution_type resolution_; resolution_type resolution_;
@ -150,6 +166,7 @@ private:
double filter_factor_; double filter_factor_;
box2d<double> unbuffered_bbox_; box2d<double> unbuffered_bbox_;
std::set<std::string> names_; std::set<std::string> names_;
attributes vars_;
}; };
} }

View file

@ -27,30 +27,33 @@
#include <mapnik/font_engine_freetype.hpp> // for face_manager, etc #include <mapnik/font_engine_freetype.hpp> // for face_manager, etc
#include <mapnik/box2d.hpp> // for box2d #include <mapnik/box2d.hpp> // for box2d
#include <mapnik/ctrans.hpp> // for CoordTransform #include <mapnik/ctrans.hpp> // for CoordTransform
#include <mapnik/attribute.hpp>
// fwd declarations to speed up compile // fwd declarations to speed up compile
namespace mapnik { namespace mapnik {
class label_collision_detector4; class label_collision_detector4;
class Map; class Map;
class request; class request;
// class attributes;
} }
namespace mapnik { namespace mapnik {
struct renderer_common struct renderer_common
{ {
renderer_common(Map const &m, unsigned offset_x, unsigned offset_y, renderer_common(Map const &m, attributes const& vars, unsigned offset_x, unsigned offset_y,
unsigned width, unsigned height, double scale_factor); unsigned width, unsigned height, double scale_factor);
renderer_common(Map const &m, unsigned offset_x, unsigned offset_y, renderer_common(Map const &m, attributes const& vars, unsigned offset_x, unsigned offset_y,
unsigned width, unsigned height, double scale_factor, unsigned width, unsigned height, double scale_factor,
std::shared_ptr<label_collision_detector4> detector); std::shared_ptr<label_collision_detector4> detector);
renderer_common(request const &req, unsigned offset_x, unsigned offset_y, renderer_common(request const &req, attributes const& vars, unsigned offset_x, unsigned offset_y,
unsigned width, unsigned height, double scale_factor); unsigned width, unsigned height, double scale_factor);
renderer_common(const renderer_common &); renderer_common(renderer_common const& other);
unsigned width_; unsigned width_;
unsigned height_; unsigned height_;
double scale_factor_; double scale_factor_;
attributes vars_;
// TODO: dirty hack for cairo renderer, figure out how to remove this // TODO: dirty hack for cairo renderer, figure out how to remove this
std::shared_ptr<freetype_engine> shared_font_engine_; std::shared_ptr<freetype_engine> shared_font_engine_;
freetype_engine &font_engine_; freetype_engine &font_engine_;
@ -61,7 +64,7 @@ struct renderer_common
private: private:
renderer_common(unsigned width, unsigned height, double scale_factor, renderer_common(unsigned width, unsigned height, double scale_factor,
CoordTransform &&t, std::shared_ptr<label_collision_detector4> detector); attributes const& vars, CoordTransform &&t, std::shared_ptr<label_collision_detector4> detector);
}; };
} }

View file

@ -115,7 +115,8 @@ struct render_thunk_extractor : public boost::static_visitor<>
{ {
render_thunk_extractor(box2d<double> &box, render_thunk_extractor(box2d<double> &box,
render_thunk_list &thunks, render_thunk_list &thunks,
mapnik::feature_impl &feature, feature_impl &feature,
attributes const& vars,
proj_transform const &prj_trans, proj_transform const &prj_trans,
renderer_common &common, renderer_common &common,
box2d<double> const &clipping_extent); box2d<double> const &clipping_extent);
@ -137,7 +138,8 @@ private:
box2d<double> &box_; box2d<double> &box_;
render_thunk_list &thunks_; render_thunk_list &thunks_;
mapnik::feature_impl &feature_; feature_impl & feature_;
attributes const& vars_;
proj_transform const &prj_trans_; proj_transform const &prj_trans_;
renderer_common &common_; renderer_common &common_;
box2d<double> clipping_extent_; box2d<double> clipping_extent_;
@ -181,9 +183,10 @@ void render_offset_placements(placements_list const& placements,
template <typename F> template <typename F>
void render_group_symbolizer(group_symbolizer const &sym, void render_group_symbolizer(group_symbolizer const &sym,
mapnik::feature_impl &feature, feature_impl & feature,
proj_transform const &prj_trans, attributes const& vars,
box2d<double> const &clipping_extent, proj_transform const & prj_trans,
box2d<double> const & clipping_extent,
renderer_common &common, renderer_common &common,
F render_thunks) F render_thunks)
{ {
@ -260,7 +263,7 @@ void render_group_symbolizer(group_symbolizer const &sym,
// get the layout for this set of properties // get the layout for this set of properties
for (auto const& rule : props->get_rules()) for (auto const& rule : props->get_rules())
{ {
if (boost::apply_visitor(evaluate<Feature,value_type>(*sub_feature), if (boost::apply_visitor(evaluate<Feature,value_type,attributes>(*sub_feature,common.vars_),
*(rule->get_filter())).to_bool()) *(rule->get_filter())).to_bool())
{ {
// add matched rule and feature to the list of things to draw // add matched rule and feature to the list of things to draw
@ -269,7 +272,7 @@ void render_group_symbolizer(group_symbolizer const &sym,
// construct a bounding box around all symbolizers for the matched rule // construct a bounding box around all symbolizers for the matched rule
bound_box bounds; bound_box bounds;
render_thunk_list thunks; render_thunk_list thunks;
render_thunk_extractor extractor(bounds, thunks, *sub_feature, prj_trans, render_thunk_extractor extractor(bounds, thunks, *sub_feature, common.vars_, prj_trans,
virtual_renderer, clipping_extent); virtual_renderer, clipping_extent);
for (auto const& sym : *rule) for (auto const& sym : *rule)
@ -288,7 +291,7 @@ void render_group_symbolizer(group_symbolizer const &sym,
} }
// create a symbolizer helper // create a symbolizer helper
group_symbolizer_helper helper(sym, feature, prj_trans, group_symbolizer_helper helper(sym, feature, vars, prj_trans,
common.width_, common.height_, common.width_, common.height_,
common.scale_factor_, common.t_, common.scale_factor_, common.t_,
*common.detector_, clipping_extent); *common.detector_, clipping_extent);
@ -316,7 +319,7 @@ void render_group_symbolizer(group_symbolizer const &sym,
// evalute the repeat key with the matched sub feature if we have one // evalute the repeat key with the matched sub feature if we have one
if (rpt_key_expr) if (rpt_key_expr)
{ {
rpt_key_value = boost::apply_visitor(evaluate<Feature,value_type>(*match_feature), *rpt_key_expr).to_unicode(); rpt_key_value = boost::apply_visitor(evaluate<Feature,value_type,attributes>(*match_feature,common.vars_), *rpt_key_expr).to_unicode();
} }
helper.add_box_element(layout_manager.offset_box_at(i), rpt_key_value); helper.add_box_element(layout_manager.offset_box_at(i), rpt_key_value);
} }

View file

@ -48,9 +48,9 @@ void render_markers_symbolizer(markers_symbolizer const &sym,
typedef boost::mpl::vector<clip_poly_tag,transform_tag,smooth_tag> conv_types; typedef boost::mpl::vector<clip_poly_tag,transform_tag,smooth_tag> conv_types;
typedef agg::pod_bvector<path_attributes> svg_attribute_type; typedef agg::pod_bvector<path_attributes> svg_attribute_type;
std::string filename = get<std::string>(sym, keys::file, feature, "shape://ellipse"); std::string filename = get<std::string>(sym, keys::file, feature, common.vars_, "shape://ellipse");
bool clip = get<value_bool>(sym, keys::clip, feature, false); bool clip = get<value_bool>(sym, keys::clip, feature, common.vars_, false);
double smooth = get<value_double>(sym, keys::smooth, feature, false); double smooth = get<value_double>(sym, keys::smooth, feature, common.vars_, false);
// https://github.com/mapnik/mapnik/issues/1316 // https://github.com/mapnik/mapnik/issues/1316
bool snap_pixels = !mapnik::marker_cache::instance().is_uri(filename); bool snap_pixels = !mapnik::marker_cache::instance().is_uri(filename);
@ -76,11 +76,11 @@ void render_markers_symbolizer(markers_symbolizer const &sym,
svg_storage_type marker_ellipse; svg_storage_type marker_ellipse;
vertex_stl_adapter<svg_path_storage> stl_storage(marker_ellipse.source()); vertex_stl_adapter<svg_path_storage> stl_storage(marker_ellipse.source());
svg_path_adapter svg_path(stl_storage); svg_path_adapter svg_path(stl_storage);
build_ellipse(sym, feature, marker_ellipse, svg_path); build_ellipse(sym, feature, common.vars_, marker_ellipse, svg_path);
svg_attribute_type attributes; svg_attribute_type attributes;
bool result = push_explicit_style( (*stock_vector_marker)->attributes(), attributes, sym); bool result = push_explicit_style( (*stock_vector_marker)->attributes(), attributes, sym, feature, common.vars_);
auto image_transform = get_optional<transform_type>(sym, keys::image_transform); auto image_transform = get_optional<transform_type>(sym, keys::image_transform);
if (image_transform) evaluate_transform(tr, feature, *image_transform); if (image_transform) evaluate_transform(tr, feature, common.vars_, *image_transform);
box2d<double> bbox = marker_ellipse.bounding_box(); box2d<double> bbox = marker_ellipse.bounding_box();
auto rasterizer_dispatch = make_vector_dispatch( auto rasterizer_dispatch = make_vector_dispatch(
@ -90,7 +90,7 @@ void render_markers_symbolizer(markers_symbolizer const &sym,
vertex_converter<box2d<double>, dispatch_type, markers_symbolizer, vertex_converter<box2d<double>, dispatch_type, markers_symbolizer,
CoordTransform, proj_transform, agg::trans_affine, conv_types, feature_impl> CoordTransform, proj_transform, agg::trans_affine, conv_types, feature_impl>
converter(clip_box, rasterizer_dispatch, sym,common.t_,prj_trans,tr,feature,common.scale_factor_); converter(clip_box, rasterizer_dispatch, sym,common.t_,prj_trans,tr,feature,common.vars_,common.scale_factor_);
if (clip && feature.paths().size() > 0) // optional clip (default: true) if (clip && feature.paths().size() > 0) // optional clip (default: true)
{ {
geometry_type::types type = feature.paths()[0].type(); geometry_type::types type = feature.paths()[0].type();
@ -103,18 +103,18 @@ void render_markers_symbolizer(markers_symbolizer const &sym,
} }
converter.template set<transform_tag>(); //always transform converter.template set<transform_tag>(); //always transform
if (smooth > 0.0) converter.template set<smooth_tag>(); // optional smooth converter if (smooth > 0.0) converter.template set<smooth_tag>(); // optional smooth converter
apply_markers_multi(feature, converter, sym); apply_markers_multi(feature, common.vars_, converter, sym);
} }
else else
{ {
box2d<double> const& bbox = (*mark)->bounding_box(); box2d<double> const& bbox = (*mark)->bounding_box();
setup_transform_scaling(tr, bbox.width(), bbox.height(), feature, sym); setup_transform_scaling(tr, bbox.width(), bbox.height(), feature, common.vars_, sym);
auto image_transform = get_optional<transform_type>(sym, keys::image_transform); auto image_transform = get_optional<transform_type>(sym, keys::image_transform);
if (image_transform) evaluate_transform(tr, feature, *image_transform); if (image_transform) evaluate_transform(tr, feature, common.vars_, *image_transform);
vertex_stl_adapter<svg_path_storage> stl_storage((*stock_vector_marker)->source()); vertex_stl_adapter<svg_path_storage> stl_storage((*stock_vector_marker)->source());
svg_path_adapter svg_path(stl_storage); svg_path_adapter svg_path(stl_storage);
svg_attribute_type attributes; svg_attribute_type attributes;
bool result = push_explicit_style( (*stock_vector_marker)->attributes(), attributes, sym); bool result = push_explicit_style( (*stock_vector_marker)->attributes(), attributes, sym, feature, common.vars_);
auto rasterizer_dispatch = make_vector_dispatch( auto rasterizer_dispatch = make_vector_dispatch(
svg_path, result ? attributes : (*stock_vector_marker)->attributes(), svg_path, result ? attributes : (*stock_vector_marker)->attributes(),
**stock_vector_marker, bbox, tr, snap_pixels); **stock_vector_marker, bbox, tr, snap_pixels);
@ -122,7 +122,7 @@ void render_markers_symbolizer(markers_symbolizer const &sym,
vertex_converter<box2d<double>, dispatch_type, markers_symbolizer, vertex_converter<box2d<double>, dispatch_type, markers_symbolizer,
CoordTransform, proj_transform, agg::trans_affine, conv_types, feature_impl> CoordTransform, proj_transform, agg::trans_affine, conv_types, feature_impl>
converter(clip_box, rasterizer_dispatch, sym,common.t_,prj_trans,tr,feature,common.scale_factor_); converter(clip_box, rasterizer_dispatch, sym,common.t_,prj_trans,tr,feature,common.vars_,common.scale_factor_);
if (clip && feature.paths().size() > 0) // optional clip (default: true) if (clip && feature.paths().size() > 0) // optional clip (default: true)
{ {
geometry_type::types type = feature.paths()[0].type(); geometry_type::types type = feature.paths()[0].type();
@ -135,14 +135,14 @@ void render_markers_symbolizer(markers_symbolizer const &sym,
} }
converter.template set<transform_tag>(); //always transform converter.template set<transform_tag>(); //always transform
if (smooth > 0.0) converter.template set<smooth_tag>(); // optional smooth converter if (smooth > 0.0) converter.template set<smooth_tag>(); // optional smooth converter
apply_markers_multi(feature, converter, sym); apply_markers_multi(feature, common.vars_, converter, sym);
} }
} }
else // raster markers else // raster markers
{ {
setup_transform_scaling(tr, (*mark)->width(), (*mark)->height(), feature, sym); setup_transform_scaling(tr, (*mark)->width(), (*mark)->height(), feature, common.vars_, sym);
auto image_transform = get_optional<transform_type>(sym, keys::image_transform); auto image_transform = get_optional<transform_type>(sym, keys::image_transform);
if (image_transform) evaluate_transform(tr, feature, *image_transform); if (image_transform) evaluate_transform(tr, feature, common.vars_, *image_transform);
box2d<double> const& bbox = (*mark)->bounding_box(); box2d<double> const& bbox = (*mark)->bounding_box();
boost::optional<mapnik::image_ptr> marker = (*mark)->get_bitmap_data(); boost::optional<mapnik::image_ptr> marker = (*mark)->get_bitmap_data();
@ -151,7 +151,7 @@ void render_markers_symbolizer(markers_symbolizer const &sym,
vertex_converter<box2d<double>, dispatch_type, markers_symbolizer, vertex_converter<box2d<double>, dispatch_type, markers_symbolizer,
CoordTransform, proj_transform, agg::trans_affine, conv_types, feature_impl> CoordTransform, proj_transform, agg::trans_affine, conv_types, feature_impl>
converter(clip_box, rasterizer_dispatch, sym,common.t_,prj_trans,tr,feature,common.scale_factor_); converter(clip_box, rasterizer_dispatch, sym,common.t_,prj_trans,tr,feature,common.vars_,common.scale_factor_);
if (clip && feature.paths().size() > 0) // optional clip (default: true) if (clip && feature.paths().size() > 0) // optional clip (default: true)
{ {
@ -165,7 +165,7 @@ void render_markers_symbolizer(markers_symbolizer const &sym,
} }
converter.template set<transform_tag>(); //always transform converter.template set<transform_tag>(); //always transform
if (smooth > 0.0) converter.template set<smooth_tag>(); // optional smooth converter if (smooth > 0.0) converter.template set<smooth_tag>(); // optional smooth converter
apply_markers_multi(feature, converter, sym); apply_markers_multi(feature, common.vars_, converter, sym);
} }
} }
} }

View file

@ -36,9 +36,9 @@ void render_point_symbolizer(point_symbolizer const &sym,
renderer_common &common, renderer_common &common,
F render_marker) F render_marker)
{ {
std::string filename = get<std::string>(sym, keys::file, feature); std::string filename = get<std::string>(sym, keys::file, feature, common.vars_);
boost::optional<mapnik::marker_ptr> marker; boost::optional<mapnik::marker_ptr> marker;
if ( !filename.empty() ) if (!filename.empty())
{ {
marker = marker_cache::instance().find(filename, true); marker = marker_cache::instance().find(filename, true);
} }
@ -46,20 +46,19 @@ void render_point_symbolizer(point_symbolizer const &sym,
{ {
marker.reset(std::make_shared<mapnik::marker>()); marker.reset(std::make_shared<mapnik::marker>());
} }
if (marker) if (marker)
{ {
double opacity = get<double>(sym,keys::opacity,feature, 1.0); double opacity = get<double>(sym,keys::opacity,feature, common.vars_, 1.0);
bool allow_overlap = get<bool>(sym, keys::allow_overlap, feature, false); bool allow_overlap = get<bool>(sym, keys::allow_overlap, feature, common.vars_, false);
bool ignore_placement = get<bool>(sym, keys::ignore_placement, feature, false); bool ignore_placement = get<bool>(sym, keys::ignore_placement, feature, common.vars_, false);
point_placement_enum placement= get<point_placement_enum>(sym, keys::point_placement_type, feature, CENTROID_POINT_PLACEMENT); point_placement_enum placement= get<point_placement_enum>(sym, keys::point_placement_type, feature, common.vars_, CENTROID_POINT_PLACEMENT);
box2d<double> const& bbox = (*marker)->bounding_box(); box2d<double> const& bbox = (*marker)->bounding_box();
coord2d center = bbox.center(); coord2d center = bbox.center();
agg::trans_affine tr; agg::trans_affine tr;
auto image_transform = get_optional<transform_type>(sym, keys::image_transform); auto image_transform = get_optional<transform_type>(sym, keys::image_transform);
if (image_transform) evaluate_transform(tr, feature, *image_transform); if (image_transform) evaluate_transform(tr, feature, common.vars_, *image_transform);
agg::trans_affine_translation recenter(-center.x, -center.y); agg::trans_affine_translation recenter(-center.x, -center.y);
agg::trans_affine recenter_tr = recenter * tr; agg::trans_affine recenter_tr = recenter * tr;

View file

@ -36,15 +36,15 @@ void render_polygon_symbolizer(polygon_symbolizer const &sym,
{ {
agg::trans_affine tr; agg::trans_affine tr;
auto transform = get_optional<transform_type>(sym, keys::geometry_transform); auto transform = get_optional<transform_type>(sym, keys::geometry_transform);
if (transform) evaluate_transform(tr, feature, *transform, common.scale_factor_); if (transform) evaluate_transform(tr, feature, common.vars_, *transform, common.scale_factor_);
bool clip = get<value_bool>(sym, keys::clip, feature, true); bool clip = get<value_bool>(sym, keys::clip, feature, common.vars_, true);
double simplify_tolerance = get<double>(sym, keys::simplify_tolerance, feature, 0.0); double simplify_tolerance = get<double>(sym, keys::simplify_tolerance, feature, common.vars_, 0.0);
double smooth = get<value_double>(sym, keys::smooth, feature, 0.0); double smooth = get<value_double>(sym, keys::smooth, feature, common.vars_, 0.0);
double opacity = get<value_double>(sym,keys::fill_opacity,feature, 1.0); double opacity = get<value_double>(sym,keys::fill_opacity,feature,common.vars_, 1.0);
vertex_converter_type converter(clip_box, ras, sym, common.t_, prj_trans, tr, vertex_converter_type converter(clip_box, ras, sym, common.t_, prj_trans, tr,
feature,common.scale_factor_); feature,common.vars_,common.scale_factor_);
if (prj_trans.equal() && clip) converter.template set<clip_poly_tag>(); //optional clip (default: true) if (prj_trans.equal() && clip) converter.template set<clip_poly_tag>(); //optional clip (default: true)
converter.template set<transform_tag>(); //always transform converter.template set<transform_tag>(); //always transform
@ -60,7 +60,7 @@ void render_polygon_symbolizer(polygon_symbolizer const &sym,
} }
} }
color const& fill = get<mapnik::color>(sym, keys::fill, feature, mapnik::color(128,128,128)); // gray color const& fill = get<mapnik::color>(sym, keys::fill, feature, common.vars_, mapnik::color(128,128,128)); // gray
fill_func(fill, opacity); fill_func(fill, opacity);
} }

View file

@ -23,6 +23,9 @@
#ifndef MAPNIK_RENDERER_COMMON_PROCESS_RASTER_SYMBOLIZER_HPP #ifndef MAPNIK_RENDERER_COMMON_PROCESS_RASTER_SYMBOLIZER_HPP
#define MAPNIK_RENDERER_COMMON_PROCESS_RASTER_SYMBOLIZER_HPP #define MAPNIK_RENDERER_COMMON_PROCESS_RASTER_SYMBOLIZER_HPP
// mapnik
#include <mapnik/warp.hpp>
// agg // agg
#include "agg_rendering_buffer.h" #include "agg_rendering_buffer.h"
#include "agg_pixfmt_rgba.h" #include "agg_pixfmt_rgba.h"
@ -55,13 +58,11 @@ void render_raster_symbolizer(raster_symbolizer const &sym,
int raster_height = end_y - start_y; int raster_height = end_y - start_y;
if (raster_width > 0 && raster_height > 0) if (raster_width > 0 && raster_height > 0)
{ {
raster target(target_ext, raster_width, raster_height, source->get_filter_factor()); scaling_method_e scaling_method = get<scaling_method_e>(sym, keys::scaling, feature, common.vars_, SCALING_NEAR);
scaling_method_e scaling_method = get<scaling_method_e>(sym, keys::scaling, feature, SCALING_NEAR); composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, common.vars_, src_over);
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, src_over); double opacity = get<double>(sym,keys::opacity,feature, common.vars_, 1.0);
double opacity = get<double>(sym,keys::opacity,feature, 1.0);
bool premultiply_source = !source->premultiplied_alpha_; bool premultiply_source = !source->premultiplied_alpha_;
auto is_premultiplied = get_optional<bool>(sym, keys::premultiplied); auto is_premultiplied = get_optional<bool>(sym, keys::premultiplied, feature, common.vars_);
if (is_premultiplied) if (is_premultiplied)
{ {
if (*is_premultiplied) premultiply_source = false; if (*is_premultiplied) premultiply_source = false;
@ -80,7 +81,8 @@ void render_raster_symbolizer(raster_symbolizer const &sym,
{ {
double offset_x = ext.minx() - start_x; double offset_x = ext.minx() - start_x;
double offset_y = ext.miny() - start_y; double offset_y = ext.miny() - start_y;
unsigned mesh_size = static_cast<unsigned>(get<value_integer>(sym,keys::mesh_size,feature, 16)); raster target(target_ext, raster_width, raster_height, source->get_filter_factor());
unsigned mesh_size = static_cast<unsigned>(get<value_integer>(sym,keys::mesh_size,feature, common.vars_, 16));
reproject_and_scale_raster(target, reproject_and_scale_raster(target,
*source, *source,
prj_trans, prj_trans,
@ -88,31 +90,46 @@ void render_raster_symbolizer(raster_symbolizer const &sym,
offset_y, offset_y,
mesh_size, mesh_size,
scaling_method); scaling_method);
composite(target.data_, comp_op, opacity, start_x, start_y);
} }
else else
{ {
if (scaling_method == SCALING_BILINEAR8) double image_ratio_x = ext.width() / source->data_.width();
double image_ratio_y = ext.height() / source->data_.height();
double eps = 1e-5;
if ( (std::fabs(image_ratio_x - 1) <= eps) &&
(std::fabs(image_ratio_y - 1) <= eps) &&
(std::fabs(start_x) <= eps) &&
(std::fabs(start_y) <= eps) )
{ {
scale_image_bilinear8<image_data_32>(target.data_, composite(source->data_, comp_op, opacity, start_x, start_y);
source->data_,
0.0,
0.0);
} }
else else
{ {
double image_ratio_x = ext.width() / source->data_.width(); raster target(target_ext, raster_width, raster_height, source->get_filter_factor());
double image_ratio_y = ext.height() / source->data_.height(); if (scaling_method == SCALING_BILINEAR8)
scale_image_agg<image_data_32>(target.data_, {
source->data_, scale_image_bilinear8<image_data_32>(target.data_,
scaling_method, source->data_,
image_ratio_x, 0.0,
image_ratio_y, 0.0);
0.0, }
0.0, else
source->get_filter_factor()); {
double image_ratio_x = ext.width() / source->data_.width();
double image_ratio_y = ext.height() / source->data_.height();
scale_image_agg<image_data_32>(target.data_,
source->data_,
scaling_method,
image_ratio_x,
image_ratio_y,
0.0,
0.0,
source->get_filter_factor());
}
composite(target.data_, comp_op, opacity, start_x, start_y);
} }
} }
composite(target, comp_op, opacity, start_x, start_y);
} }
} }
} }

View file

@ -74,7 +74,7 @@ class MAPNIK_DECL svg_renderer : public feature_style_processor<svg_renderer<Out
public: public:
typedef svg_renderer<OutputIterator> processor_impl_type; typedef svg_renderer<OutputIterator> processor_impl_type;
svg_renderer(Map const& m, OutputIterator& output_iterator, double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0); svg_renderer(Map const& m, OutputIterator& output_iterator, double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0);
svg_renderer(Map const& m, request const& req, OutputIterator& output_iterator, double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0); svg_renderer(Map const& m, request const& req, attributes const& vars, OutputIterator& output_iterator, double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0);
~svg_renderer(); ~svg_renderer();
void start_map_processing(Map const& map); void start_map_processing(Map const& map);
@ -147,6 +147,11 @@ public:
return common_.scale_factor_; return common_.scale_factor_;
} }
inline attributes const& variables() const
{
return common_.vars_;
}
inline OutputIterator& get_output_iterator() inline OutputIterator& get_output_iterator()
{ {
return output_iterator_; return output_iterator_;

View file

@ -29,6 +29,7 @@
#include <mapnik/image_compositing.hpp> #include <mapnik/image_compositing.hpp>
#include <mapnik/simplify.hpp> #include <mapnik/simplify.hpp>
#include <mapnik/expression.hpp> #include <mapnik/expression.hpp>
#include <mapnik/attribute.hpp>
#include <mapnik/expression_evaluator.hpp> #include <mapnik/expression_evaluator.hpp>
#include <mapnik/path_expression.hpp> #include <mapnik/path_expression.hpp>
#include <mapnik/parse_path.hpp> #include <mapnik/parse_path.hpp>
@ -38,6 +39,8 @@
#include <mapnik/text/placements/dummy.hpp> #include <mapnik/text/placements/dummy.hpp>
#include <mapnik/raster_colorizer.hpp> #include <mapnik/raster_colorizer.hpp>
#include <mapnik/group/group_symbolizer_properties.hpp> #include <mapnik/group/group_symbolizer_properties.hpp>
#include <mapnik/attribute.hpp>
// stl // stl
#include <type_traits> #include <type_traits>
#include <algorithm> #include <algorithm>
@ -63,6 +66,7 @@ class feature_impl;
MAPNIK_DECL void evaluate_transform(agg::trans_affine& tr, MAPNIK_DECL void evaluate_transform(agg::trans_affine& tr,
feature_impl const& feature, feature_impl const& feature,
attributes const& vars,
transform_type const& trans_expr, transform_type const& trans_expr,
double scale_factor=1.0); double scale_factor=1.0);
@ -245,10 +249,10 @@ struct evaluate_expression_wrapper
{ {
typedef T result_type; typedef T result_type;
template <typename T1, typename T2> template <typename T1, typename T2, typename T3>
result_type operator() (T1 const& expr, T2 const& feature) const result_type operator() (T1 const& expr, T2 const& feature, T3 const& vars) const
{ {
mapnik::value_type result = boost::apply_visitor(mapnik::evaluate<mapnik::feature_impl,mapnik::value_type>(feature), expr); mapnik::value_type result = boost::apply_visitor(mapnik::evaluate<T2,mapnik::value_type,T3>(feature,vars), expr);
return detail::expression_result<result_type, std::is_enum<result_type>::value>::convert(result); return detail::expression_result<result_type, std::is_enum<result_type>::value>::convert(result);
} }
}; };
@ -257,10 +261,10 @@ struct evaluate_expression_wrapper
template <> template <>
struct evaluate_expression_wrapper<mapnik::color> struct evaluate_expression_wrapper<mapnik::color>
{ {
template <typename T1, typename T2> template <typename T1, typename T2, typename T3>
mapnik::color operator() (T1 const& expr, T2 const& feature) const mapnik::color operator() (T1 const& expr, T2 const& feature, T3 const& vars) const
{ {
mapnik::value_type val = boost::apply_visitor(mapnik::evaluate<mapnik::feature_impl,mapnik::value_type>(feature), expr); mapnik::value_type val = boost::apply_visitor(mapnik::evaluate<T2,mapnik::value_type,T3>(feature,vars), expr);
// FIXME - throw instead? // FIXME - throw instead?
if (val.is_null()) return mapnik::color(255,192,203); // pink if (val.is_null()) return mapnik::color(255,192,203); // pink
return mapnik::color(val.to_string()); return mapnik::color(val.to_string());
@ -271,10 +275,10 @@ struct evaluate_expression_wrapper<mapnik::color>
template <> template <>
struct evaluate_expression_wrapper<mapnik::enumeration_wrapper> struct evaluate_expression_wrapper<mapnik::enumeration_wrapper>
{ {
template <typename T1, typename T2> template <typename T1, typename T2, typename T3>
mapnik::enumeration_wrapper operator() (T1 const& expr, T2 const& feature) const mapnik::enumeration_wrapper operator() (T1 const& expr, T2 const& feature, T3 const& vars) const
{ {
mapnik::value_type val = boost::apply_visitor(mapnik::evaluate<mapnik::feature_impl,mapnik::value_type>(feature), expr); mapnik::value_type val = boost::apply_visitor(mapnik::evaluate<T2,mapnik::value_type,T3>(feature,vars), expr);
return mapnik::enumeration_wrapper(val.to_int()); return mapnik::enumeration_wrapper(val.to_int());
} }
}; };
@ -285,12 +289,14 @@ struct extract_value : public boost::static_visitor<T>
{ {
typedef T result_type; typedef T result_type;
extract_value(mapnik::feature_impl const& feature) extract_value(mapnik::feature_impl const& feature,
: feature_(feature) {} mapnik::attributes const& v)
: feature_(feature),
vars_(v) {}
auto operator() (mapnik::expression_ptr const& expr) const -> result_type auto operator() (mapnik::expression_ptr const& expr) const -> result_type
{ {
return evaluate_expression_wrapper<result_type>()(*expr,feature_); return evaluate_expression_wrapper<result_type>()(*expr,feature_,vars_);
} }
auto operator() (mapnik::path_expression_ptr const& expr) const -> result_type auto operator() (mapnik::path_expression_ptr const& expr) const -> result_type
@ -308,13 +314,14 @@ struct extract_value : public boost::static_visitor<T>
return detail::enumeration_result<result_type, std::is_enum<result_type>::value>::convert(e); return detail::enumeration_result<result_type, std::is_enum<result_type>::value>::convert(e);
} }
template <typename T1> template <typename TVal>
auto operator() (T1 const& val) const -> result_type auto operator() (TVal const& val) const -> result_type
{ {
return result_type(); return result_type();
} }
mapnik::feature_impl const& feature_; mapnik::feature_impl const& feature_;
mapnik::attributes const& vars_;
}; };
template <typename T1> template <typename T1>
@ -353,25 +360,25 @@ bool has_key(symbolizer_base const& sym, keys key)
} }
template <typename T> template <typename T>
T get(symbolizer_base const& sym, keys key, mapnik::feature_impl const& feature, T const& _default_value = T()) T get(symbolizer_base const& sym, keys key, mapnik::feature_impl const& feature, attributes const& vars, T const& _default_value = T())
{ {
typedef symbolizer_base::cont_type::const_iterator const_iterator; typedef symbolizer_base::cont_type::const_iterator const_iterator;
const_iterator itr = sym.properties.find(key); const_iterator itr = sym.properties.find(key);
if (itr != sym.properties.end()) if (itr != sym.properties.end())
{ {
return boost::apply_visitor(extract_value<T>(feature), itr->second); return boost::apply_visitor(extract_value<T>(feature,vars), itr->second);
} }
return _default_value; return _default_value;
} }
template <typename T> template <typename T>
boost::optional<T> get_optional(symbolizer_base const& sym, keys key, mapnik::feature_impl const& feature) boost::optional<T> get_optional(symbolizer_base const& sym, keys key, mapnik::feature_impl const& feature, attributes const& vars)
{ {
typedef symbolizer_base::cont_type::const_iterator const_iterator; typedef symbolizer_base::cont_type::const_iterator const_iterator;
const_iterator itr = sym.properties.find(key); const_iterator itr = sym.properties.find(key);
if (itr != sym.properties.end()) if (itr != sym.properties.end())
{ {
return boost::apply_visitor(extract_value<T>(feature), itr->second); return boost::apply_visitor(extract_value<T>(feature,vars), itr->second);
} }
return boost::optional<T>(); return boost::optional<T>();
} }

View file

@ -82,6 +82,8 @@ enum class keys : std::uint8_t
start_column, start_column,
repeat_key, repeat_key,
group_properties, group_properties,
largest_box_only,
minimum_path_length,
MAX_SYMBOLIZER_KEY MAX_SYMBOLIZER_KEY
}; };

View file

@ -46,7 +46,7 @@ public:
virtual ~node() {} virtual ~node() {}
virtual void to_xml(boost::property_tree::ptree &xml) const; virtual void to_xml(boost::property_tree::ptree &xml) const;
static node_ptr from_xml(xml_node const& xml); static node_ptr from_xml(xml_node const& xml);
virtual void apply(char_properties_ptr p, feature_impl const& feature, text_layout &output) const = 0; virtual void apply(char_properties_ptr p, feature_impl const& feature, attributes const& vars, text_layout &output) const = 0;
virtual void add_expressions(expression_set &output) const; virtual void add_expressions(expression_set &output) const;
}; };
} //ns formatting } //ns formatting

View file

@ -40,7 +40,7 @@ class MAPNIK_DECL expression_format: public node {
public: public:
void to_xml(boost::property_tree::ptree &xml) const; void to_xml(boost::property_tree::ptree &xml) const;
static node_ptr from_xml(xml_node const& xml); static node_ptr from_xml(xml_node const& xml);
virtual void apply(char_properties_ptr p, feature_impl const& feature, text_layout &output) const; virtual void apply(char_properties_ptr p, feature_impl const& feature, attributes const& vars, text_layout &output) const;
virtual void add_expressions(expression_set &output) const; virtual void add_expressions(expression_set &output) const;
void set_child(node_ptr child); void set_child(node_ptr child);

View file

@ -36,7 +36,7 @@ class MAPNIK_DECL format_node: public node {
public: public:
void to_xml(boost::property_tree::ptree &xml) const; void to_xml(boost::property_tree::ptree &xml) const;
static node_ptr from_xml(xml_node const& xml); static node_ptr from_xml(xml_node const& xml);
virtual void apply(char_properties_ptr p, feature_impl const& feature, text_layout &output) const; virtual void apply(char_properties_ptr p, feature_impl const& feature, attributes const& vars, text_layout &output) const;
virtual void add_expressions(expression_set &output) const; virtual void add_expressions(expression_set &output) const;
void set_child(node_ptr child); void set_child(node_ptr child);

View file

@ -34,7 +34,7 @@ class MAPNIK_DECL layout_node: public node {
public: public:
void to_xml(boost::property_tree::ptree &xml) const; void to_xml(boost::property_tree::ptree &xml) const;
static node_ptr from_xml(xml_node const& xml); static node_ptr from_xml(xml_node const& xml);
virtual void apply(char_properties_ptr p, feature_impl const& feature, text_layout &output) const; virtual void apply(char_properties_ptr p, feature_impl const& feature, attributes const& vars, text_layout &output) const;
virtual void add_expressions(expression_set &output) const; virtual void add_expressions(expression_set &output) const;
void set_child(node_ptr child); void set_child(node_ptr child);
node_ptr get_child() const; node_ptr get_child() const;

View file

@ -35,7 +35,7 @@ class MAPNIK_DECL list_node: public node {
public: public:
list_node() : node(), children_() {} list_node() : node(), children_() {}
virtual void to_xml(boost::property_tree::ptree &xml) const; virtual void to_xml(boost::property_tree::ptree &xml) const;
virtual void apply(char_properties_ptr p, feature_impl const& feature, text_layout &output) const; virtual void apply(char_properties_ptr p, feature_impl const& feature, attributes const& vars, text_layout &output) const;
virtual void add_expressions(expression_set &output) const; virtual void add_expressions(expression_set &output) const;
void push_back(node_ptr n); void push_back(node_ptr n);

View file

@ -36,7 +36,7 @@ public:
text_node(std::string text): node(), text_(parse_expression(text)) {} text_node(std::string text): node(), text_(parse_expression(text)) {}
void to_xml(boost::property_tree::ptree &xml) const; void to_xml(boost::property_tree::ptree &xml) const;
static node_ptr from_xml(xml_node const& xml); static node_ptr from_xml(xml_node const& xml);
virtual void apply(char_properties_ptr p, feature_impl const& feature, text_layout &output) const; virtual void apply(char_properties_ptr p, feature_impl const& feature, attributes const& vars, text_layout &output) const;
virtual void add_expressions(expression_set &output) const; virtual void add_expressions(expression_set &output) const;
void set_text(expression_ptr text); void set_text(expression_ptr text);

View file

@ -101,7 +101,7 @@ public:
pixel_position alignment_offset() const; pixel_position alignment_offset() const;
double jalign_offset(double line_width) const; double jalign_offset(double line_width) const;
void init_orientation(feature_impl const& feature); void init_orientation(feature_impl const& feature, attributes const& attr);
private: private:
void break_line(text_line & line, double wrap_width, unsigned text_ratio, bool wrap_before); void break_line(text_line & line, double wrap_width, unsigned text_ratio, bool wrap_before);

View file

@ -45,6 +45,7 @@ class placement_finder : mapnik::noncopyable
{ {
public: public:
placement_finder(feature_impl const& feature, placement_finder(feature_impl const& feature,
attributes const& attr,
DetectorType & detector, DetectorType & detector,
box2d<double> const& extent, box2d<double> const& extent,
text_placement_info_ptr placement_info, text_placement_info_ptr placement_info,
@ -79,6 +80,7 @@ private:
text_upright_e simplify_upright(text_upright_e upright, double angle) const; text_upright_e simplify_upright(text_upright_e upright, double angle) const;
box2d<double> get_bbox(text_layout const& layout, glyph_info const& glyph, pixel_position const& pos, rotation const& rot); box2d<double> get_bbox(text_layout const& layout, glyph_info const& glyph, pixel_position const& pos, rotation const& rot);
feature_impl const& feature_; feature_impl const& feature_;
attributes const& attr_;
DetectorType &detector_; DetectorType &detector_;
box2d<double> const& extent_; box2d<double> const& extent_;
text_placement_info_ptr info_; text_placement_info_ptr info_;

View file

@ -38,6 +38,7 @@ class base_symbolizer_helper
public: public:
base_symbolizer_helper(symbolizer_base const& sym, base_symbolizer_helper(symbolizer_base const& sym,
feature_impl const& feature, feature_impl const& feature,
attributes const& vars,
proj_transform const& prj_trans, proj_transform const& prj_trans,
unsigned width, unsigned width,
unsigned height, unsigned height,
@ -52,6 +53,7 @@ protected:
//Input //Input
symbolizer_base const& sym_; symbolizer_base const& sym_;
feature_impl const& feature_; feature_impl const& feature_;
attributes const& vars_;
proj_transform const& prj_trans_; proj_transform const& prj_trans_;
CoordTransform const& t_; CoordTransform const& t_;
box2d<double> dims_; box2d<double> dims_;
@ -84,6 +86,7 @@ public:
template <typename FaceManagerT, typename DetectorT> template <typename FaceManagerT, typename DetectorT>
text_symbolizer_helper(text_symbolizer const& sym, text_symbolizer_helper(text_symbolizer const& sym,
feature_impl const& feature, feature_impl const& feature,
attributes const& vars,
proj_transform const& prj_trans, proj_transform const& prj_trans,
unsigned width, unsigned width,
unsigned height, unsigned height,
@ -96,6 +99,7 @@ public:
template <typename FaceManagerT, typename DetectorT> template <typename FaceManagerT, typename DetectorT>
text_symbolizer_helper(shield_symbolizer const& sym, text_symbolizer_helper(shield_symbolizer const& sym,
feature_impl const& feature, feature_impl const& feature,
attributes const& vars,
proj_transform const& prj_trans, proj_transform const& prj_trans,
unsigned width, unsigned width,
unsigned height, unsigned height,

View file

@ -175,7 +175,7 @@ struct MAPNIK_DECL text_symbolizer_properties
/** Takes a feature and produces formated text as output. /** Takes a feature and produces formated text as output.
* The output object has to be created by the caller and passed in for thread safety. * The output object has to be created by the caller and passed in for thread safety.
*/ */
void process(text_layout &output, feature_impl const& feature) const; void process(text_layout &output, feature_impl const& feature, attributes const& vars) const;
/** Automatically create processing instructions for a single expression. */ /** Automatically create processing instructions for a single expression. */
void set_old_style_expression(expression_ptr expr); void set_old_style_expression(expression_ptr expr);
/** Sets new format tree. */ /** Sets new format tree. */

View file

@ -46,10 +46,11 @@ class feature_impl;
template <typename Container> struct expression_attributes; template <typename Container> struct expression_attributes;
template <typename T> template <typename T, typename T1>
struct transform_processor struct transform_processor
{ {
typedef T feature_type; typedef T feature_type;
typedef T1 variable_type;
typedef agg::trans_affine transform_type; typedef agg::trans_affine transform_type;
template <typename Container> template <typename Container>
@ -109,9 +110,11 @@ struct transform_processor
{ {
node_evaluator(transform_type& tr, node_evaluator(transform_type& tr,
feature_type const& feat, feature_type const& feat,
variable_type const& v,
double scale_factor) double scale_factor)
: transform_(tr), : transform_(tr),
feature_(feat), feature_(feat),
vars_(v),
scale_factor_(scale_factor) {} scale_factor_(scale_factor) {}
void operator() (identity_node const& node) void operator() (identity_node const& node)
@ -175,7 +178,7 @@ struct transform_processor
double eval(expr_node const& x) const double eval(expr_node const& x) const
{ {
mapnik::evaluate<feature_type, value_type> e(feature_); mapnik::evaluate<feature_type, value_type, variable_type> e(feature_,vars_);
return boost::apply_visitor(e, x).to_double(); return boost::apply_visitor(e, x).to_double();
} }
@ -186,6 +189,7 @@ struct transform_processor
transform_type& transform_; transform_type& transform_;
feature_type const& feature_; feature_type const& feature_;
variable_type const& vars_;
double scale_factor_; double scale_factor_;
}; };
@ -201,10 +205,13 @@ struct transform_processor
} }
} }
static void evaluate(transform_type& tr, feature_type const& feat, static void evaluate(transform_type& tr,
transform_list const& list, double scale_factor) feature_type const& feat,
variable_type const& vars,
transform_list const& list,
double scale_factor)
{ {
node_evaluator eval(tr, feat, scale_factor); node_evaluator eval(tr, feat, vars, scale_factor);
#ifdef MAPNIK_LOG #ifdef MAPNIK_LOG
MAPNIK_LOG_DEBUG(transform) << "transform: begin with " << to_string(matrix_node(tr)); MAPNIK_LOG_DEBUG(transform) << "transform: begin with " << to_string(matrix_node(tr));
@ -235,7 +242,7 @@ struct transform_processor
} }
}; };
typedef mapnik::transform_processor<feature_impl> transform_processor_type; typedef mapnik::transform_processor<feature_impl,attributes> transform_processor_type;
} // namespace mapnik } // namespace mapnik

View file

@ -99,7 +99,8 @@ struct converter_traits<T,mapnik::smooth_tag>
{ {
typename boost::mpl::at<Args,boost::mpl::int_<2> >::type sym = boost::fusion::at_c<2>(args); typename boost::mpl::at<Args,boost::mpl::int_<2> >::type sym = boost::fusion::at_c<2>(args);
auto const& feat = boost::fusion::at_c<6>(args); auto const& feat = boost::fusion::at_c<6>(args);
geom.smooth_value(get<value_double>(sym, keys::smooth, feat)); auto const& vars = boost::fusion::at_c<7>(args);
geom.smooth_value(get<value_double>(sym, keys::smooth, feat, vars));
} }
}; };
@ -114,8 +115,9 @@ struct converter_traits<T,mapnik::simplify_tag>
{ {
typename boost::mpl::at<Args,boost::mpl::int_<2> >::type sym = boost::fusion::at_c<2>(args); typename boost::mpl::at<Args,boost::mpl::int_<2> >::type sym = boost::fusion::at_c<2>(args);
auto const& feat = boost::fusion::at_c<6>(args); auto const& feat = boost::fusion::at_c<6>(args);
geom.set_simplify_algorithm(static_cast<simplify_algorithm_e>(get<value_integer>(sym, keys::simplify_algorithm, feat))); auto const& vars = boost::fusion::at_c<7>(args);
geom.set_simplify_tolerance(get<value_double>(sym, keys::simplify_tolerance, feat)); geom.set_simplify_algorithm(static_cast<simplify_algorithm_e>(get<value_integer>(sym, keys::simplify_algorithm, feat, vars)));
geom.set_simplify_tolerance(get<value_double>(sym, keys::simplify_tolerance, feat, vars));
} }
}; };
@ -143,7 +145,7 @@ struct converter_traits<T, mapnik::dash_tag>
static void setup(geometry_type & geom, Args const& args) static void setup(geometry_type & geom, Args const& args)
{ {
typename boost::mpl::at<Args,boost::mpl::int_<2> >::type sym = boost::fusion::at_c<2>(args); typename boost::mpl::at<Args,boost::mpl::int_<2> >::type sym = boost::fusion::at_c<2>(args);
double scale_factor = boost::fusion::at_c<7>(args); double scale_factor = boost::fusion::at_c<8>(args);
auto dash = get_optional<dash_array>(sym, keys::stroke_dasharray); auto dash = get_optional<dash_array>(sym, keys::stroke_dasharray);
if (dash) if (dash)
{ {
@ -167,11 +169,12 @@ struct converter_traits<T, mapnik::stroke_tag>
{ {
typename boost::mpl::at<Args,boost::mpl::int_<2> >::type sym = boost::fusion::at_c<2>(args); typename boost::mpl::at<Args,boost::mpl::int_<2> >::type sym = boost::fusion::at_c<2>(args);
auto const& feat = boost::fusion::at_c<6>(args); auto const& feat = boost::fusion::at_c<6>(args);
set_join_caps(sym, geom, feat); auto const& vars = boost::fusion::at_c<7>(args);
double miterlimit = get<value_double>(sym, keys::stroke_miterlimit, feat, 4.0); set_join_caps(sym, geom, feat, vars);
double miterlimit = get<value_double>(sym, keys::stroke_miterlimit, feat, vars, 4.0);
geom.generator().miter_limit(miterlimit); geom.generator().miter_limit(miterlimit);
double scale_factor = boost::fusion::at_c<7>(args); double scale_factor = boost::fusion::at_c<8>(args);
double width = get<value_double>(sym, keys::stroke_width, feat, 1.0); double width = get<value_double>(sym, keys::stroke_width, feat, vars, 1.0);
geom.generator().width(width * scale_factor); geom.generator().width(width * scale_factor);
} }
}; };
@ -248,8 +251,9 @@ struct converter_traits<T,mapnik::offset_transform_tag>
{ {
typename boost::mpl::at<Args,boost::mpl::int_<2> >::type sym = boost::fusion::at_c<2>(args); typename boost::mpl::at<Args,boost::mpl::int_<2> >::type sym = boost::fusion::at_c<2>(args);
auto const& feat = boost::fusion::at_c<6>(args); auto const& feat = boost::fusion::at_c<6>(args);
double offset = get<value_double>(sym, keys::offset, feat); auto const& vars = boost::fusion::at_c<7>(args);
double scale_factor = boost::fusion::at_c<7>(args); double offset = get<value_double>(sym, keys::offset, feat, vars);
double scale_factor = boost::fusion::at_c<8>(args);
geom.set_offset(offset * scale_factor); geom.set_offset(offset * scale_factor);
} }
}; };
@ -351,6 +355,7 @@ struct vertex_converter : private mapnik::noncopyable
proj_trans_type const&, proj_trans_type const&,
affine_trans_type const&, affine_trans_type const&,
feature_type const&, feature_type const&,
attributes const&,
double //scale-factor double //scale-factor
> args_type; > args_type;
@ -361,6 +366,7 @@ struct vertex_converter : private mapnik::noncopyable
proj_trans_type const& prj_trans, proj_trans_type const& prj_trans,
affine_trans_type const& affine_trans, affine_trans_type const& affine_trans,
feature_type const& feature, feature_type const& feature,
attributes const& vars,
double scale_factor) double scale_factor)
: disp_(args_type(boost::cref(b), : disp_(args_type(boost::cref(b),
boost::ref(ras), boost::ref(ras),
@ -369,6 +375,7 @@ struct vertex_converter : private mapnik::noncopyable
boost::cref(prj_trans), boost::cref(prj_trans),
boost::cref(affine_trans), boost::cref(affine_trans),
boost::cref(feature), boost::cref(feature),
boost::cref(vars),
scale_factor)) {} scale_factor)) {}
template <typename Geometry> template <typename Geometry>

View file

@ -28,7 +28,10 @@
#include <mapnik/util/conversions.hpp> #include <mapnik/util/conversions.hpp>
// webp // webp
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-function"
#include <webp/encode.h> #include <webp/encode.h>
#pragma clang diagnostic pop
// stl // stl
#include <stdexcept> #include <stdexcept>

View file

@ -54,6 +54,7 @@ if env['PLUGIN_LINKING'] == 'shared':
libraries.insert(0,'mapnik') libraries.insert(0,'mapnik')
libraries.append(env['ICU_LIB_NAME']) libraries.append(env['ICU_LIB_NAME'])
libraries.append('boost_system%s' % env['BOOST_APPEND']) libraries.append('boost_system%s' % env['BOOST_APPEND'])
libraries.append('boost_regex%s' % env['BOOST_APPEND'])
TARGET = plugin_env.SharedLibrary('../%s' % PLUGIN_NAME, TARGET = plugin_env.SharedLibrary('../%s' % PLUGIN_NAME,
SHLIBPREFIX='', SHLIBPREFIX='',

View file

@ -38,6 +38,7 @@
// boost // boost
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <boost/tokenizer.hpp> #include <boost/tokenizer.hpp>
#include <boost/regex.hpp>
// stl // stl
#include <memory> #include <memory>
@ -85,9 +86,11 @@ postgis_datasource::postgis_datasource(parameters const& params)
extent_from_subquery_(*params.get<mapnik::boolean>("extent_from_subquery", false)), extent_from_subquery_(*params.get<mapnik::boolean>("extent_from_subquery", false)),
max_async_connections_(*params_.get<mapnik::value_integer>("max_async_connection", 1)), max_async_connections_(*params_.get<mapnik::value_integer>("max_async_connection", 1)),
asynchronous_request_(false), asynchronous_request_(false),
// TODO - use for known tokens too: "(@\\w+|!\\w+!)"
pattern_(boost::regex("(@\\w+)",boost::regex::normal | boost::regbase::icase)),
// params below are for testing purposes only and may be removed at any time // params below are for testing purposes only and may be removed at any time
intersect_min_scale_(*params.get<mapnik::value_integer>("intersect_min_scale", 0)), intersect_min_scale_(*params.get<mapnik::value_integer>("intersect_min_scale", 0)),
intersect_max_scale_(*params.get<mapnik::value_integer>("intersect_max_scale", 0)) intersect_max_scale_(*params.get<mapnik::value_integer>("intersect_max_scale", 0))
{ {
#ifdef MAPNIK_STATS #ifdef MAPNIK_STATS
mapnik::progress_timer __stats__(std::clog, "postgis_datasource::init"); mapnik::progress_timer __stats__(std::clog, "postgis_datasource::init");
@ -520,22 +523,34 @@ std::string postgis_datasource::populate_tokens(std::string const& sql) const
if (boost::algorithm::icontains(sql, pixel_width_token_)) if (boost::algorithm::icontains(sql, pixel_width_token_))
{ {
std::ostringstream ss; boost::algorithm::replace_all(populated_sql, pixel_width_token_, "0");
ss << 0;
boost::algorithm::replace_all(populated_sql, pixel_width_token_, ss.str());
} }
if (boost::algorithm::icontains(sql, pixel_height_token_)) if (boost::algorithm::icontains(sql, pixel_height_token_))
{ {
std::ostringstream ss; boost::algorithm::replace_all(populated_sql, pixel_height_token_, "0");
ss << 0;
boost::algorithm::replace_all(populated_sql, pixel_height_token_, ss.str());
} }
std::string copy2 = populated_sql;
std::list<std::string> l;
boost::regex_split(std::back_inserter(l), copy2, pattern_);
if (!l.empty())
{
for (auto const & token: l)
{
boost::algorithm::replace_all(populated_sql, token, "null");
}
}
return populated_sql; return populated_sql;
} }
std::string postgis_datasource::populate_tokens(std::string const& sql, double scale_denom, box2d<double> const& env, double pixel_width, double pixel_height) const std::string postgis_datasource::populate_tokens(
std::string const& sql,
double scale_denom,
box2d<double> const& env,
double pixel_width,
double pixel_height,
mapnik::attributes const& vars) const
{ {
std::string populated_sql = sql; std::string populated_sql = sql;
std::string box = sql_bbox(env); std::string box = sql_bbox(env);
@ -564,7 +579,6 @@ std::string postgis_datasource::populate_tokens(std::string const& sql, double s
if (boost::algorithm::icontains(populated_sql, bbox_token_)) if (boost::algorithm::icontains(populated_sql, bbox_token_))
{ {
boost::algorithm::replace_all(populated_sql, bbox_token_, box); boost::algorithm::replace_all(populated_sql, bbox_token_, box);
return populated_sql;
} }
else else
{ {
@ -582,9 +596,27 @@ std::string postgis_datasource::populate_tokens(std::string const& sql, double s
{ {
s << " WHERE \"" << geometryColumn_ << "\" && " << box; s << " WHERE \"" << geometryColumn_ << "\" && " << box;
} }
populated_sql += s.str();
return populated_sql + s.str();
} }
std::string copy2 = populated_sql;
std::list<std::string> l;
boost::regex_split(std::back_inserter(l), copy2, pattern_);
if (!l.empty())
{
for (auto const & token: l)
{
auto itr = vars.find(token.substr(1,std::string::npos));
if (itr != vars.end())
{
boost::algorithm::replace_all(populated_sql, token, itr->second.to_string());
}
else
{
boost::algorithm::replace_all(populated_sql, token, "null");
}
}
}
return populated_sql;
} }
@ -780,7 +812,7 @@ featureset_ptr postgis_datasource::features_with_context(query const& q,processo
} }
} }
std::string table_with_bbox = populate_tokens(table_, scale_denom, box, px_gw, px_gh); std::string table_with_bbox = populate_tokens(table_, scale_denom, box, px_gw, px_gh, q.variables());
s << " FROM " << table_with_bbox; s << " FROM " << table_with_bbox;
@ -863,7 +895,7 @@ featureset_ptr postgis_datasource::features_at_point(coord2d const& pt, double t
} }
box2d<double> box(pt.x - tol, pt.y - tol, pt.x + tol, pt.y + tol); box2d<double> box(pt.x - tol, pt.y - tol, pt.x + tol, pt.y + tol);
std::string table_with_bbox = populate_tokens(table_, FMAX, box, 0, 0); std::string table_with_bbox = populate_tokens(table_, FMAX, box, 0, 0, mapnik::attributes());
s << " FROM " << table_with_bbox; s << " FROM " << table_with_bbox;

View file

@ -33,9 +33,11 @@
#include <mapnik/feature_layer_desc.hpp> #include <mapnik/feature_layer_desc.hpp>
#include <mapnik/unicode.hpp> #include <mapnik/unicode.hpp>
#include <mapnik/value_types.hpp> #include <mapnik/value_types.hpp>
#include <mapnik/attribute.hpp>
// boost // boost
#include <boost/optional.hpp> #include <boost/optional.hpp>
#include <boost/regex.hpp>
// stl // stl
#include <memory> #include <memory>
@ -77,7 +79,12 @@ public:
private: private:
std::string sql_bbox(box2d<double> const& env) const; std::string sql_bbox(box2d<double> const& env) const;
std::string populate_tokens(std::string const& sql, double scale_denom, box2d<double> const& env, double pixel_width, double pixel_height) const; std::string populate_tokens(std::string const& sql,
double scale_denom,
box2d<double> const& env,
double pixel_width,
double pixel_height,
mapnik::attributes const& vars) const;
std::string populate_tokens(std::string const& sql) const; std::string populate_tokens(std::string const& sql) const;
std::shared_ptr<IResultSet> get_resultset(std::shared_ptr<Connection> &conn, std::string const& sql, CnxPool_ptr const& pool, processor_context_ptr ctx= processor_context_ptr()) const; std::shared_ptr<IResultSet> get_resultset(std::shared_ptr<Connection> &conn, std::string const& sql, CnxPool_ptr const& pool, processor_context_ptr ctx= processor_context_ptr()) const;
static const std::string GEOMETRY_COLUMNS; static const std::string GEOMETRY_COLUMNS;
@ -112,6 +119,7 @@ private:
bool estimate_extent_; bool estimate_extent_;
int max_async_connections_; int max_async_connections_;
bool asynchronous_request_; bool asynchronous_request_;
boost::regex pattern_;
int intersect_min_scale_; int intersect_min_scale_;
int intersect_max_scale_; int intersect_max_scale_;
}; };

View file

@ -72,13 +72,13 @@ agg_renderer<T0,T1>::agg_renderer(Map const& m, T0 & pixmap, double scale_factor
ras_ptr(new rasterizer), ras_ptr(new rasterizer),
gamma_method_(GAMMA_POWER), gamma_method_(GAMMA_POWER),
gamma_(1.0), gamma_(1.0),
common_(m, offset_x, offset_y, m.width(), m.height(), scale_factor) common_(m, attributes(), offset_x, offset_y, m.width(), m.height(), scale_factor)
{ {
setup(m); setup(m);
} }
template <typename T0, typename T1> template <typename T0, typename T1>
agg_renderer<T0,T1>::agg_renderer(Map const& m, request const& req, T0 & pixmap, double scale_factor, unsigned offset_x, unsigned offset_y) agg_renderer<T0,T1>::agg_renderer(Map const& m, request const& req, attributes const& vars, T0 & pixmap, double scale_factor, unsigned offset_x, unsigned offset_y)
: feature_style_processor<agg_renderer>(m, scale_factor), : feature_style_processor<agg_renderer>(m, scale_factor),
pixmap_(pixmap), pixmap_(pixmap),
internal_buffer_(), internal_buffer_(),
@ -87,7 +87,7 @@ agg_renderer<T0,T1>::agg_renderer(Map const& m, request const& req, T0 & pixmap,
ras_ptr(new rasterizer), ras_ptr(new rasterizer),
gamma_method_(GAMMA_POWER), gamma_method_(GAMMA_POWER),
gamma_(1.0), gamma_(1.0),
common_(req, offset_x, offset_y, req.width(), req.height(), scale_factor) common_(req, vars, offset_x, offset_y, req.width(), req.height(), scale_factor)
{ {
setup(m); setup(m);
} }
@ -103,7 +103,7 @@ agg_renderer<T0,T1>::agg_renderer(Map const& m, T0 & pixmap, std::shared_ptr<T1>
ras_ptr(new rasterizer), ras_ptr(new rasterizer),
gamma_method_(GAMMA_POWER), gamma_method_(GAMMA_POWER),
gamma_(1.0), gamma_(1.0),
common_(m, offset_x, offset_y, m.width(), m.height(), scale_factor, detector) common_(m, attributes(), offset_x, offset_y, m.width(), m.height(), scale_factor, detector)
{ {
setup(m); setup(m);
} }

View file

@ -61,8 +61,8 @@ void agg_renderer<T0,T1>::process(building_symbolizer const& sym,
agg::pixfmt_rgba32_pre pixf(buf); agg::pixfmt_rgba32_pre pixf(buf);
ren_base renb(pixf); ren_base renb(pixf);
double opacity = get<value_double>(sym,keys::fill_opacity,feature, 1.0); double opacity = get<value_double>(sym,keys::fill_opacity,feature, common_.vars_, 1.0);
color const& fill = get<mapnik::color>(sym, keys::fill, feature); color const& fill = get<mapnik::color>(sym, keys::fill, feature, common_.vars_, mapnik::color(128,128,128));
unsigned r=fill.red(); unsigned r=fill.red();
unsigned g=fill.green(); unsigned g=fill.green();
unsigned b=fill.blue(); unsigned b=fill.blue();
@ -71,8 +71,8 @@ void agg_renderer<T0,T1>::process(building_symbolizer const& sym,
agg::scanline_u8 sl; agg::scanline_u8 sl;
ras_ptr->reset(); ras_ptr->reset();
double gamma = get<value_double>(sym, keys::gamma, feature, 1.0); double gamma = get<value_double>(sym, keys::gamma, feature, common_.vars_, 1.0);
gamma_method_enum gamma_method = get<gamma_method_enum>(sym, keys::gamma_method, feature, GAMMA_POWER); gamma_method_enum gamma_method = get<gamma_method_enum>(sym, keys::gamma_method, feature, common_.vars_, GAMMA_POWER);
if (gamma != gamma_ || gamma_method != gamma_method_) if (gamma != gamma_ || gamma_method != gamma_method_)
{ {
set_gamma_method(ras_ptr, gamma, gamma_method); set_gamma_method(ras_ptr, gamma, gamma_method);
@ -80,7 +80,7 @@ void agg_renderer<T0,T1>::process(building_symbolizer const& sym,
gamma_ = gamma; gamma_ = gamma;
} }
double height = get<double>(sym, keys::height,0.0) * common_.scale_factor_; double height = get<double>(sym, keys::height, feature, common_.vars_,0.0) * common_.scale_factor_;
render_building_symbolizer( render_building_symbolizer(
feature, height, feature, height,

View file

@ -53,7 +53,7 @@ void agg_renderer<T0,T1>::process(debug_symbolizer const& sym,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
debug_symbolizer_mode_enum mode = get<debug_symbolizer_mode_enum>(sym, keys::mode, DEBUG_SYM_MODE_COLLISION); debug_symbolizer_mode_enum mode = get<debug_symbolizer_mode_enum>(sym, keys::mode, feature, common_.vars_, DEBUG_SYM_MODE_COLLISION);
if (mode == DEBUG_SYM_MODE_COLLISION) if (mode == DEBUG_SYM_MODE_COLLISION)
{ {

View file

@ -106,7 +106,7 @@ void agg_renderer<T0,T1>::process(group_symbolizer const& sym,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
render_group_symbolizer( render_group_symbolizer(
sym, feature, prj_trans, clipping_extent(), common_, sym, feature, common_.vars_, prj_trans, clipping_extent(), common_,
[&](render_thunk_list const& thunks, pixel_position const& render_offset) [&](render_thunk_list const& thunks, pixel_position const& render_offset)
{ {
thunk_renderer ren(*this, current_buffer_, common_, render_offset); thunk_renderer ren(*this, current_buffer_, common_, render_offset);

View file

@ -100,9 +100,9 @@ void agg_renderer<T0,T1>::process(line_pattern_symbolizer const& sym,
typedef agg::renderer_outline_image<renderer_base, pattern_type> renderer_type; typedef agg::renderer_outline_image<renderer_base, pattern_type> renderer_type;
typedef agg::rasterizer_outline_aa<renderer_type> rasterizer_type; typedef agg::rasterizer_outline_aa<renderer_type> rasterizer_type;
std::string filename = get<std::string>(sym, keys::file, feature); std::string filename = get<std::string>(sym, keys::file, feature, common_.vars_);
if (filename.empty()) return;
boost::optional<marker_ptr> mark = marker_cache::instance().find(filename,true); boost::optional<mapnik::marker_ptr> mark = marker_cache::instance().find(filename, true);
if (!mark) return; if (!mark) return;
if (!(*mark)->is_bitmap()) if (!(*mark)->is_bitmap())
@ -114,16 +114,15 @@ void agg_renderer<T0,T1>::process(line_pattern_symbolizer const& sym,
boost::optional<image_ptr> pat = (*mark)->get_bitmap_data(); boost::optional<image_ptr> pat = (*mark)->get_bitmap_data();
if (!pat) return; if (!pat) return;
bool clip = get<value_bool>(sym, keys::clip, feature, common_.vars_, true);
bool clip = get<value_bool>(sym, keys::clip, feature);
//double opacity = get<value_double>(sym,keys::stroke_opacity,feature, 1.0); TODO //double opacity = get<value_double>(sym,keys::stroke_opacity,feature, 1.0); TODO
double offset = get<value_double>(sym, keys::offset, feature, 0.0); double offset = get<value_double>(sym, keys::offset, feature, common_.vars_, 0.0);
double simplify_tolerance = get<value_double>(sym, keys::simplify_tolerance, feature, 0.0); double simplify_tolerance = get<value_double>(sym, keys::simplify_tolerance, feature, common_.vars_, 0.0);
double smooth = get<value_double>(sym, keys::smooth, feature, false); double smooth = get<value_double>(sym, keys::smooth, feature, common_.vars_, false);
agg::rendering_buffer buf(current_buffer_->raw_data(),current_buffer_->width(),current_buffer_->height(), current_buffer_->width() * 4); agg::rendering_buffer buf(current_buffer_->raw_data(),current_buffer_->width(),current_buffer_->height(), current_buffer_->width() * 4);
pixfmt_type pixf(buf); pixfmt_type pixf(buf);
pixf.comp_op(get<agg::comp_op_e>(sym, keys::comp_op, feature, agg::comp_op_src_over)); pixf.comp_op(get<agg::comp_op_e>(sym, keys::comp_op, feature, common_.vars_, agg::comp_op_src_over));
renderer_base ren_base(pixf); renderer_base ren_base(pixf);
agg::pattern_filter_bilinear_rgba8 filter; agg::pattern_filter_bilinear_rgba8 filter;
@ -134,7 +133,7 @@ void agg_renderer<T0,T1>::process(line_pattern_symbolizer const& sym,
agg::trans_affine tr; agg::trans_affine tr;
auto transform = get_optional<transform_type>(sym, keys::geometry_transform); auto transform = get_optional<transform_type>(sym, keys::geometry_transform);
if (transform) evaluate_transform(tr, feature, *transform, common_.scale_factor_); if (transform) evaluate_transform(tr, feature, common_.vars_, *transform, common_.scale_factor_);
box2d<double> clip_box = clipping_extent(); box2d<double> clip_box = clipping_extent();
if (clip) if (clip)
@ -152,7 +151,7 @@ void agg_renderer<T0,T1>::process(line_pattern_symbolizer const& sym,
typedef boost::mpl::vector<clip_line_tag,transform_tag,offset_transform_tag,affine_transform_tag,simplify_tag,smooth_tag> conv_types; typedef boost::mpl::vector<clip_line_tag,transform_tag,offset_transform_tag,affine_transform_tag,simplify_tag,smooth_tag> conv_types;
vertex_converter<box2d<double>, rasterizer_type, line_pattern_symbolizer, vertex_converter<box2d<double>, rasterizer_type, line_pattern_symbolizer,
CoordTransform, proj_transform, agg::trans_affine, conv_types, feature_impl> CoordTransform, proj_transform, agg::trans_affine, conv_types, feature_impl>
converter(clip_box,ras,sym,common_.t_,prj_trans,tr,feature,common_.scale_factor_); converter(clip_box,ras,sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_);
if (clip) converter.set<clip_line_tag>(); //optional clip (default: true) if (clip) converter.set<clip_line_tag>(); //optional clip (default: true)
converter.set<transform_tag>(); //always transform converter.set<transform_tag>(); //always transform

View file

@ -26,7 +26,6 @@
#include <mapnik/agg_renderer.hpp> #include <mapnik/agg_renderer.hpp>
#include <mapnik/agg_helpers.hpp> #include <mapnik/agg_helpers.hpp>
#include <mapnik/agg_rasterizer.hpp> #include <mapnik/agg_rasterizer.hpp>
#include <mapnik/symbolizer.hpp> #include <mapnik/symbolizer.hpp>
#include <mapnik/vertex_converters.hpp> #include <mapnik/vertex_converters.hpp>
@ -59,14 +58,14 @@ void agg_renderer<T0,T1>::process(line_symbolizer const& sym,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
color const& col = get<color>(sym, keys::stroke, feature, mapnik::color(0,0,0)); color const& col = get<color>(sym, keys::stroke, feature, common_.vars_, mapnik::color(0,0,0));
unsigned r=col.red(); unsigned r=col.red();
unsigned g=col.green(); unsigned g=col.green();
unsigned b=col.blue(); unsigned b=col.blue();
unsigned a=col.alpha(); unsigned a=col.alpha();
double gamma = get<value_double>(sym, keys::stroke_gamma, feature, 1.0); double gamma = get<value_double>(sym, keys::stroke_gamma, feature, common_.vars_, 1.0);
gamma_method_enum gamma_method = get<gamma_method_enum>(sym, keys::stroke_gamma_method, feature, GAMMA_POWER); gamma_method_enum gamma_method = get<gamma_method_enum>(sym, keys::stroke_gamma_method, feature, common_.vars_, GAMMA_POWER);
ras_ptr->reset(); ras_ptr->reset();
if (gamma != gamma_ || gamma_method != gamma_method_) if (gamma != gamma_ || gamma_method != gamma_method_)
@ -90,22 +89,22 @@ void agg_renderer<T0,T1>::process(line_symbolizer const& sym,
dash_tag, stroke_tag> conv_types; dash_tag, stroke_tag> conv_types;
pixfmt_comp_type pixf(buf); pixfmt_comp_type pixf(buf);
pixf.comp_op(get<agg::comp_op_e>(sym, keys::comp_op, feature, agg::comp_op_src_over)); pixf.comp_op(get<agg::comp_op_e>(sym, keys::comp_op, feature, common_.vars_, agg::comp_op_src_over));
renderer_base renb(pixf); renderer_base renb(pixf);
agg::trans_affine tr; agg::trans_affine tr;
auto transform = get_optional<transform_type>(sym, keys::geometry_transform); auto transform = get_optional<transform_type>(sym, keys::geometry_transform);
if (transform) evaluate_transform(tr, feature, *transform, common_.scale_factor_); if (transform) evaluate_transform(tr, feature, common_.vars_, *transform, common_.scale_factor_);
box2d<double> clip_box = clipping_extent(); box2d<double> clip_box = clipping_extent();
bool clip = get<value_bool>(sym, keys::clip, feature, true); bool clip = get<value_bool>(sym, keys::clip, feature, common_.vars_, true);
double width = get<value_double>(sym, keys::stroke_width, feature, 1.0); double width = get<value_double>(sym, keys::stroke_width, feature, common_.vars_, 1.0);
double opacity = get<value_double>(sym,keys::stroke_opacity,feature, 1.0); double opacity = get<value_double>(sym,keys::stroke_opacity,feature, common_.vars_, 1.0);
double offset = get<value_double>(sym, keys::offset, feature, 0.0); double offset = get<value_double>(sym, keys::offset, feature, common_.vars_, 0.0);
double simplify_tolerance = get<value_double>(sym, keys::simplify_tolerance, feature, 0.0); double simplify_tolerance = get<value_double>(sym, keys::simplify_tolerance, feature, common_.vars_, 0.0);
double smooth = get<value_double>(sym, keys::smooth, feature, false); double smooth = get<value_double>(sym, keys::smooth, feature, common_.vars_, false);
line_rasterizer_enum rasterizer_e = get<line_rasterizer_enum>(sym, keys::line_rasterizer, feature, RASTERIZER_FULL); line_rasterizer_enum rasterizer_e = get<line_rasterizer_enum>(sym, keys::line_rasterizer, feature, common_.vars_, RASTERIZER_FULL);
if (clip) if (clip)
{ {
double padding = static_cast<double>(common_.query_extent_.width()/pixmap_.width()); double padding = static_cast<double>(common_.query_extent_.width()/pixmap_.width());
@ -135,11 +134,11 @@ void agg_renderer<T0,T1>::process(line_symbolizer const& sym,
renderer_type ren(renb, profile); renderer_type ren(renb, profile);
ren.color(agg::rgba8_pre(r, g, b, int(a * opacity))); ren.color(agg::rgba8_pre(r, g, b, int(a * opacity)));
rasterizer_type ras(ren); rasterizer_type ras(ren);
set_join_caps_aa(sym, ras, feature); set_join_caps_aa(sym, ras, feature, common_.vars_);
vertex_converter<box2d<double>, rasterizer_type, line_symbolizer, vertex_converter<box2d<double>, rasterizer_type, line_symbolizer,
CoordTransform, proj_transform, agg::trans_affine, conv_types, feature_impl> CoordTransform, proj_transform, agg::trans_affine, conv_types, feature_impl>
converter(clip_box,ras,sym,common_.t_,prj_trans,tr,feature,common_.scale_factor_); converter(clip_box,ras,sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_);
if (clip) converter.set<clip_line_tag>(); // optional clip (default: true) if (clip) converter.set<clip_line_tag>(); // optional clip (default: true)
converter.set<transform_tag>(); // always transform converter.set<transform_tag>(); // always transform
if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset
@ -159,7 +158,7 @@ void agg_renderer<T0,T1>::process(line_symbolizer const& sym,
{ {
vertex_converter<box2d<double>, rasterizer, line_symbolizer, vertex_converter<box2d<double>, rasterizer, line_symbolizer,
CoordTransform, proj_transform, agg::trans_affine, conv_types, feature_impl> CoordTransform, proj_transform, agg::trans_affine, conv_types, feature_impl>
converter(clip_box,*ras_ptr,sym,common_.t_,prj_trans,tr,feature,common_.scale_factor_); converter(clip_box,*ras_ptr,sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_);
if (clip) converter.set<clip_line_tag>(); // optional clip (default: true) if (clip) converter.set<clip_line_tag>(); // optional clip (default: true)
converter.set<transform_tag>(); // always transform converter.set<transform_tag>(); // always transform

View file

@ -28,7 +28,6 @@
#include <mapnik/debug.hpp> #include <mapnik/debug.hpp>
#include <mapnik/feature.hpp> #include <mapnik/feature.hpp>
#include <mapnik/geom_util.hpp> #include <mapnik/geom_util.hpp>
#include <mapnik/vertex_converters.hpp>
#include <mapnik/marker_helpers.hpp> #include <mapnik/marker_helpers.hpp>
#include <mapnik/marker.hpp> #include <mapnik/marker.hpp>
#include <mapnik/marker_cache.hpp> #include <mapnik/marker_cache.hpp>
@ -83,8 +82,8 @@ void agg_renderer<T0,T1>::process(markers_symbolizer const& sym,
detector_type > vector_dispatch_type; detector_type > vector_dispatch_type;
typedef raster_markers_rasterizer_dispatch<buf_type,rasterizer, detector_type> raster_dispatch_type; typedef raster_markers_rasterizer_dispatch<buf_type,rasterizer, detector_type> raster_dispatch_type;
double gamma = get<value_double>(sym, keys::gamma, feature, 1.0); double gamma = get<value_double>(sym, keys::gamma, feature, common_.vars_, 1.0);
gamma_method_enum gamma_method = get<gamma_method_enum>(sym, keys::gamma_method, feature, GAMMA_POWER); gamma_method_enum gamma_method = get<gamma_method_enum>(sym, keys::gamma_method, feature, common_.vars_, GAMMA_POWER);
if (gamma != gamma_ || gamma_method != gamma_method_) if (gamma != gamma_ || gamma_method != gamma_method_)
{ {
set_gamma_method(ras_ptr, gamma, gamma_method); set_gamma_method(ras_ptr, gamma, gamma_method);
@ -112,6 +111,7 @@ void agg_renderer<T0,T1>::process(markers_symbolizer const& sym,
marker_trans, marker_trans,
sym, sym,
*common_.detector_, *common_.detector_,
feature, common_.vars_,
common_.scale_factor_, common_.scale_factor_,
snap_pixels); snap_pixels);
}, },
@ -126,6 +126,7 @@ void agg_renderer<T0,T1>::process(markers_symbolizer const& sym,
marker_trans, marker_trans,
sym, sym,
*common_.detector_, *common_.detector_,
feature, common_.vars_,
common_.scale_factor_, common_.scale_factor_,
true /*snap rasters no matter what*/); true /*snap rasters no matter what*/);
}); });

View file

@ -25,7 +25,6 @@
#include <mapnik/agg_renderer.hpp> #include <mapnik/agg_renderer.hpp>
#include <mapnik/agg_rasterizer.hpp> #include <mapnik/agg_rasterizer.hpp>
#include <mapnik/image_util.hpp> #include <mapnik/image_util.hpp>
#include <mapnik/geom_util.hpp> #include <mapnik/geom_util.hpp>
#include <mapnik/symbolizer.hpp> #include <mapnik/symbolizer.hpp>
#include <mapnik/marker.hpp> #include <mapnik/marker.hpp>
@ -50,7 +49,7 @@ void agg_renderer<T0,T1>::process(point_symbolizer const& sym,
mapnik::feature_impl & feature, mapnik::feature_impl & feature,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, src_over); composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, common_.vars_, src_over);
render_point_symbolizer( render_point_symbolizer(
sym, feature, prj_trans, common_, sym, feature, prj_trans, common_,

View file

@ -20,9 +20,6 @@
* *
*****************************************************************************/ *****************************************************************************/
// boost
// mapnik // mapnik
#include <mapnik/feature.hpp> #include <mapnik/feature.hpp>
#include <mapnik/debug.hpp> #include <mapnik/debug.hpp>
@ -57,13 +54,27 @@ void agg_renderer<T0,T1>::process(polygon_pattern_symbolizer const& sym,
mapnik::feature_impl & feature, mapnik::feature_impl & feature,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
std::string filename = get<std::string>(sym, keys::file, feature, common_.vars_);
if (filename.empty()) return;
boost::optional<mapnik::marker_ptr> marker = marker_cache::instance().find(filename, true);
if (!marker) return;
if (!(*marker)->is_bitmap())
{
MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: Only images (not '" << filename << "') are supported in the line_pattern_symbolizer";
return;
}
boost::optional<image_ptr> pat = (*marker)->get_bitmap_data();
if (!pat) return;
typedef agg::conv_clip_polygon<geometry_type> clipped_geometry_type; typedef agg::conv_clip_polygon<geometry_type> clipped_geometry_type;
typedef coord_transform<CoordTransform,clipped_geometry_type> path_type; typedef coord_transform<CoordTransform,clipped_geometry_type> path_type;
agg::rendering_buffer buf(current_buffer_->raw_data(), current_buffer_->width(), current_buffer_->height(), current_buffer_->width() * 4); agg::rendering_buffer buf(current_buffer_->raw_data(), current_buffer_->width(), current_buffer_->height(), current_buffer_->width() * 4);
ras_ptr->reset(); ras_ptr->reset();
double gamma = get<value_double>(sym, keys::gamma, feature, 1.0); double gamma = get<value_double>(sym, keys::gamma, feature, common_.vars_, 1.0);
gamma_method_enum gamma_method = get<gamma_method_enum>(sym, keys::gamma_method, feature, GAMMA_POWER); gamma_method_enum gamma_method = get<gamma_method_enum>(sym, keys::gamma_method, feature, common_.vars_, GAMMA_POWER);
if (gamma != gamma_ || gamma_method != gamma_method_) if (gamma != gamma_ || gamma_method != gamma_method_)
{ {
set_gamma_method(ras_ptr, gamma, gamma_method); set_gamma_method(ras_ptr, gamma, gamma_method);
@ -71,34 +82,10 @@ void agg_renderer<T0,T1>::process(polygon_pattern_symbolizer const& sym,
gamma_ = gamma; gamma_ = gamma;
} }
std::string filename = get<std::string>(sym, keys::file, feature); bool clip = get<value_bool>(sym, keys::clip, feature, common_.vars_, false);
boost::optional<mapnik::marker_ptr> marker; double opacity = get<double>(sym,keys::stroke_opacity, feature, common_.vars_, 1.0);
if ( !filename.empty() ) double simplify_tolerance = get<value_double>(sym, keys::simplify_tolerance, feature, common_.vars_, 0.0);
{ double smooth = get<value_double>(sym, keys::smooth, feature, common_.vars_, false);
marker = marker_cache::instance().find(filename, true);
}
else
{
MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: File not found=" << filename;
}
if (!marker) return;
if (!(*marker)->is_bitmap())
{
MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: Only images (not '" << filename << "') are supported in the polygon_pattern_symbolizer";
return;
}
boost::optional<image_ptr> pat = (*marker)->get_bitmap_data();
if (!pat) return;
bool clip = get<value_bool>(sym, keys::clip, feature, false);
double opacity = get<double>(sym,keys::stroke_opacity, 1.0);
double simplify_tolerance = get<value_double>(sym, keys::simplify_tolerance, feature, 0.0);
double smooth = get<value_double>(sym, keys::smooth, feature, false);
box2d<double> clip_box = clipping_extent(); box2d<double> clip_box = clipping_extent();
@ -121,7 +108,7 @@ void agg_renderer<T0,T1>::process(polygon_pattern_symbolizer const& sym,
span_gen_type> renderer_type; span_gen_type> renderer_type;
pixfmt_type pixf(buf); pixfmt_type pixf(buf);
pixf.comp_op(get<agg::comp_op_e>(sym, keys::comp_op, feature, agg::comp_op_src_over)); pixf.comp_op(get<agg::comp_op_e>(sym, keys::comp_op, feature, common_.vars_, agg::comp_op_src_over));
ren_base renb(pixf); ren_base renb(pixf);
unsigned w=(*pat)->width(); unsigned w=(*pat)->width();
@ -130,7 +117,7 @@ void agg_renderer<T0,T1>::process(polygon_pattern_symbolizer const& sym,
agg::pixfmt_rgba32_pre pixf_pattern(pattern_rbuf); agg::pixfmt_rgba32_pre pixf_pattern(pattern_rbuf);
img_source_type img_src(pixf_pattern); img_source_type img_src(pixf_pattern);
pattern_alignment_enum alignment = get<pattern_alignment_enum>(sym, keys::alignment, feature, LOCAL_ALIGNMENT); pattern_alignment_enum alignment = get<pattern_alignment_enum>(sym, keys::alignment, feature, common_.vars_, LOCAL_ALIGNMENT);
unsigned offset_x=0; unsigned offset_x=0;
unsigned offset_y=0; unsigned offset_y=0;
@ -156,12 +143,12 @@ void agg_renderer<T0,T1>::process(polygon_pattern_symbolizer const& sym,
agg::trans_affine tr; agg::trans_affine tr;
auto transform = get_optional<transform_type>(sym, keys::geometry_transform); auto transform = get_optional<transform_type>(sym, keys::geometry_transform);
if (transform) evaluate_transform(tr, feature, *transform, common_.scale_factor_); if (transform) evaluate_transform(tr, feature, common_.vars_, *transform, common_.scale_factor_);
typedef boost::mpl::vector<clip_poly_tag,transform_tag,affine_transform_tag,simplify_tag,smooth_tag> conv_types; typedef boost::mpl::vector<clip_poly_tag,transform_tag,affine_transform_tag,simplify_tag,smooth_tag> conv_types;
vertex_converter<box2d<double>, rasterizer, polygon_pattern_symbolizer, vertex_converter<box2d<double>, rasterizer, polygon_pattern_symbolizer,
CoordTransform, proj_transform, agg::trans_affine, conv_types, feature_impl> CoordTransform, proj_transform, agg::trans_affine, conv_types, feature_impl>
converter(clip_box,*ras_ptr,sym,common_.t_,prj_trans,tr,feature,common_.scale_factor_); converter(clip_box,*ras_ptr,sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_);
if (prj_trans.equal() && clip) converter.set<clip_poly_tag>(); //optional clip (default: true) if (prj_trans.equal() && clip) converter.set<clip_poly_tag>(); //optional clip (default: true)
converter.set<transform_tag>(); //always transform converter.set<transform_tag>(); //always transform

View file

@ -55,8 +55,8 @@ void agg_renderer<T0,T1>::process(polygon_symbolizer const& sym,
conv_types, feature_impl> vertex_converter_type; conv_types, feature_impl> vertex_converter_type;
ras_ptr->reset(); ras_ptr->reset();
double gamma = get<value_double>(sym, keys::gamma, feature, 1.0); double gamma = get<value_double>(sym, keys::gamma, feature, common_.vars_, 1.0);
gamma_method_enum gamma_method = get<gamma_method_enum>(sym, keys::gamma_method, feature, GAMMA_POWER); gamma_method_enum gamma_method = get<gamma_method_enum>(sym, keys::gamma_method, feature, common_.vars_, GAMMA_POWER);
if (gamma != gamma_ || gamma_method != gamma_method_) if (gamma != gamma_ || gamma_method != gamma_method_)
{ {
set_gamma_method(ras_ptr, gamma, gamma_method); set_gamma_method(ras_ptr, gamma, gamma_method);
@ -81,7 +81,7 @@ void agg_renderer<T0,T1>::process(polygon_symbolizer const& sym,
typedef agg::renderer_base<pixfmt_comp_type> renderer_base; typedef agg::renderer_base<pixfmt_comp_type> renderer_base;
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_type; typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_type;
pixfmt_comp_type pixf(buf); pixfmt_comp_type pixf(buf);
pixf.comp_op(get<agg::comp_op_e>(sym, keys::comp_op, feature, agg::comp_op_src_over)); pixf.comp_op(get<agg::comp_op_e>(sym, keys::comp_op, feature, common_.vars_, agg::comp_op_src_over));
renderer_base renb(pixf); renderer_base renb(pixf);
renderer_type ren(renb); renderer_type ren(renb);
ren.color(agg::rgba8_pre(r, g, b, int(a * opacity))); ren.color(agg::rgba8_pre(r, g, b, int(a * opacity)));

View file

@ -33,7 +33,6 @@
#include <mapnik/image_util.hpp> #include <mapnik/image_util.hpp>
#include <mapnik/raster.hpp> #include <mapnik/raster.hpp>
#include <mapnik/box2d.hpp> #include <mapnik/box2d.hpp>
#include <mapnik/warp.hpp>
#include <mapnik/config.hpp> #include <mapnik/config.hpp>
#include <mapnik/renderer_common/process_raster_symbolizer.hpp> #include <mapnik/renderer_common/process_raster_symbolizer.hpp>
@ -53,11 +52,12 @@ void agg_renderer<T0,T1>::process(raster_symbolizer const& sym,
{ {
render_raster_symbolizer( render_raster_symbolizer(
sym, feature, prj_trans, common_, sym, feature, prj_trans, common_,
[&](raster &target, composite_mode_e comp_op, double opacity, [&](image_data_32 & target, composite_mode_e comp_op, double opacity,
int start_x, int start_y) { int start_x, int start_y) {
composite(current_buffer_->data(), target.data_, composite(current_buffer_->data(), target,
comp_op, opacity, start_x, start_y, false); comp_op, opacity, start_x, start_y, false);
}); }
);
} }
template void agg_renderer<image_32>::process(raster_symbolizer const&, template void agg_renderer<image_32>::process(raster_symbolizer const&,

View file

@ -38,21 +38,21 @@ void agg_renderer<T0,T1>::process(shield_symbolizer const& sym,
{ {
box2d<double> clip_box = clipping_extent(); box2d<double> clip_box = clipping_extent();
text_symbolizer_helper helper( text_symbolizer_helper helper(
sym, feature, prj_trans, sym, feature, common_.vars_, prj_trans,
common_.width_, common_.height_, common_.width_, common_.height_,
common_.scale_factor_, common_.scale_factor_,
common_.t_, common_.font_manager_, *common_.detector_, common_.t_, common_.font_manager_, *common_.detector_,
clip_box); clip_box);
halo_rasterizer_enum halo_rasterizer = get<halo_rasterizer_enum>(sym, keys::halo_rasterizer, HALO_RASTERIZER_FULL); halo_rasterizer_enum halo_rasterizer = get<halo_rasterizer_enum>(sym, keys::halo_rasterizer, feature, common_.vars_, HALO_RASTERIZER_FULL);
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, src_over); composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, common_.vars_, src_over);
agg_text_renderer<T0> ren(*current_buffer_, agg_text_renderer<T0> ren(*current_buffer_,
halo_rasterizer, halo_rasterizer,
comp_op, comp_op,
common_.scale_factor_, common_.scale_factor_,
common_.font_manager_.get_stroker()); common_.font_manager_.get_stroker());
double opacity = get<double>(sym,keys::opacity,feature, 1.0); double opacity = get<double>(sym,keys::opacity, feature, common_.vars_, 1.0);
placements_list const& placements = helper.get(); placements_list const& placements = helper.get();
for (glyph_positions_ptr glyphs : placements) for (glyph_positions_ptr glyphs : placements)

View file

@ -38,14 +38,14 @@ void agg_renderer<T0,T1>::process(text_symbolizer const& sym,
box2d<double> clip_box = clipping_extent(); box2d<double> clip_box = clipping_extent();
text_symbolizer_helper helper( text_symbolizer_helper helper(
sym, feature, prj_trans, sym, feature, common_.vars_, prj_trans,
common_.width_, common_.height_, common_.width_, common_.height_,
common_.scale_factor_, common_.scale_factor_,
common_.t_, common_.font_manager_, *common_.detector_, common_.t_, common_.font_manager_, *common_.detector_,
clip_box); clip_box);
halo_rasterizer_enum halo_rasterizer = get<halo_rasterizer_enum>(sym, keys::halo_rasterizer, HALO_RASTERIZER_FULL); halo_rasterizer_enum halo_rasterizer = get<halo_rasterizer_enum>(sym, keys::halo_rasterizer,feature, common_.vars_, HALO_RASTERIZER_FULL);
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, src_over); composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, common_.vars_, src_over);
agg_text_renderer<T0> ren(*current_buffer_, agg_text_renderer<T0> ren(*current_buffer_,
halo_rasterizer, halo_rasterizer,
comp_op, comp_op,
@ -56,7 +56,7 @@ void agg_renderer<T0,T1>::process(text_symbolizer const& sym,
auto transform = get_optional<transform_type>(sym, keys::halo_transform); auto transform = get_optional<transform_type>(sym, keys::halo_transform);
if (transform) if (transform)
{ {
evaluate_transform(halo_transform, feature, *transform); evaluate_transform(halo_transform, feature, common_.vars_, *transform);
ren.set_halo_transform(halo_transform); ren.set_halo_transform(halo_transform);
} }
placements_list const& placements = helper.get(); placements_list const& placements = helper.get();

View file

@ -58,6 +58,7 @@
#include <mapnik/attribute_collector.hpp> #include <mapnik/attribute_collector.hpp>
#include <mapnik/group/group_layout_manager.hpp> #include <mapnik/group/group_layout_manager.hpp>
#include <mapnik/group/group_symbolizer_helper.hpp> #include <mapnik/group/group_symbolizer_helper.hpp>
#include <mapnik/attribute.hpp>
// mapnik symbolizer generics // mapnik symbolizer generics
#include <mapnik/renderer_common/process_building_symbolizer.hpp> #include <mapnik/renderer_common/process_building_symbolizer.hpp>
@ -108,12 +109,13 @@ struct cairo_save_restore
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,
attributes const& vars,
double scale_factor, double scale_factor,
unsigned offset_x, unsigned offset_x,
unsigned offset_y) unsigned offset_y)
: m_(m), : m_(m),
context_(cairo), context_(cairo),
common_(m, offset_x, offset_y, m.width(), m.height(), scale_factor), common_(m, vars, offset_x, offset_y, m.width(), m.height(), scale_factor),
face_manager_(common_.shared_font_engine_) face_manager_(common_.shared_font_engine_)
{ {
setup(m); setup(m);
@ -122,12 +124,13 @@ cairo_renderer_base::cairo_renderer_base(Map const& m,
cairo_renderer_base::cairo_renderer_base(Map const& m, cairo_renderer_base::cairo_renderer_base(Map const& m,
request const& req, request const& req,
cairo_ptr const& cairo, cairo_ptr const& cairo,
attributes const& vars,
double scale_factor, double scale_factor,
unsigned offset_x, unsigned offset_x,
unsigned offset_y) unsigned offset_y)
: m_(m), : m_(m),
context_(cairo), context_(cairo),
common_(req, offset_x, offset_y, req.width(), req.height(), scale_factor), common_(req, vars, offset_x, offset_y, req.width(), req.height(), scale_factor),
face_manager_(common_.shared_font_engine_) face_manager_(common_.shared_font_engine_)
{ {
setup(m); setup(m);
@ -135,13 +138,14 @@ cairo_renderer_base::cairo_renderer_base(Map const& 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,
attributes const& vars,
std::shared_ptr<label_collision_detector4> detector, std::shared_ptr<label_collision_detector4> detector,
double scale_factor, double scale_factor,
unsigned offset_x, unsigned offset_x,
unsigned offset_y) unsigned offset_y)
: m_(m), : m_(m),
context_(cairo), context_(cairo),
common_(m, offset_x, offset_y, m.width(), m.height(), scale_factor, detector), common_(m, vars, offset_x, offset_y, m.width(), m.height(), scale_factor, detector),
face_manager_(common_.shared_font_engine_) face_manager_(common_.shared_font_engine_)
{ {
MAPNIK_LOG_DEBUG(cairo_renderer) << "cairo_renderer_base: Scale=" << m.scale(); MAPNIK_LOG_DEBUG(cairo_renderer) << "cairo_renderer_base: Scale=" << m.scale();
@ -150,32 +154,32 @@ cairo_renderer_base::cairo_renderer_base(Map const& m,
template <> template <>
cairo_renderer<cairo_ptr>::cairo_renderer(Map const& m, cairo_ptr const& cairo, double scale_factor, unsigned offset_x, unsigned offset_y) cairo_renderer<cairo_ptr>::cairo_renderer(Map const& m, cairo_ptr const& cairo, 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),
cairo_renderer_base(m,cairo,scale_factor,offset_x,offset_y) {} cairo_renderer_base(m,cairo,attributes(),scale_factor,offset_x,offset_y) {}
template <> template <>
cairo_renderer<cairo_surface_ptr>::cairo_renderer(Map const& m, cairo_surface_ptr const& surface, double scale_factor, unsigned offset_x, unsigned offset_y) cairo_renderer<cairo_surface_ptr>::cairo_renderer(Map const& m, cairo_surface_ptr const& surface, 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),
cairo_renderer_base(m,create_context(surface),scale_factor,offset_x,offset_y) {} cairo_renderer_base(m,create_context(surface),attributes(),scale_factor,offset_x,offset_y) {}
template <> 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) cairo_renderer<cairo_ptr>::cairo_renderer(Map const& m, request const& req, attributes const& vars, cairo_ptr const& cairo, 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),
cairo_renderer_base(m,req,cairo,scale_factor,offset_x,offset_y) {} cairo_renderer_base(m,req,cairo,vars,scale_factor,offset_x,offset_y) {}
template <> 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) cairo_renderer<cairo_surface_ptr>::cairo_renderer(Map const& m, request const& req, attributes const& vars, cairo_surface_ptr const& surface, 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),
cairo_renderer_base(m,req, create_context(surface),scale_factor,offset_x,offset_y) {} cairo_renderer_base(m,req,create_context(surface),attributes(),scale_factor,offset_x,offset_y) {}
template <> template <>
cairo_renderer<cairo_ptr>::cairo_renderer(Map const& m, cairo_ptr const& cairo, std::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, std::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),
cairo_renderer_base(m,cairo,detector,scale_factor,offset_x,offset_y) {} cairo_renderer_base(m,cairo,attributes(),detector,scale_factor,offset_x,offset_y) {}
template <> template <>
cairo_renderer<cairo_surface_ptr>::cairo_renderer(Map const& m, cairo_surface_ptr const& surface, std::shared_ptr<label_collision_detector4> detector, double scale_factor, unsigned offset_x, unsigned offset_y) cairo_renderer<cairo_surface_ptr>::cairo_renderer(Map const& m, cairo_surface_ptr const& surface, std::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),
cairo_renderer_base(m,create_context(surface),detector,scale_factor,offset_x,offset_y) {} cairo_renderer_base(m,create_context(surface),attributes(),detector,scale_factor,offset_x,offset_y) {}
cairo_renderer_base::~cairo_renderer_base() {} cairo_renderer_base::~cairo_renderer_base() {}
@ -279,7 +283,7 @@ void cairo_renderer_base::process(polygon_symbolizer const& sym,
conv_types, feature_impl> vertex_converter_type; conv_types, feature_impl> vertex_converter_type;
cairo_save_restore guard(context_); cairo_save_restore guard(context_);
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, src_over); composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, common_.vars_, src_over);
context_.set_operator(comp_op); context_.set_operator(comp_op);
render_polygon_symbolizer<vertex_converter_type>( render_polygon_symbolizer<vertex_converter_type>(
@ -298,10 +302,10 @@ void cairo_renderer_base::process(building_symbolizer const& sym,
{ {
typedef coord_transform<CoordTransform,geometry_type> path_type; typedef coord_transform<CoordTransform,geometry_type> path_type;
cairo_save_restore guard(context_); cairo_save_restore guard(context_);
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, src_over); composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, common_.vars_, src_over);
mapnik::color fill = get<mapnik::color>(sym, keys::fill, feature); mapnik::color fill = get<mapnik::color>(sym, keys::fill, feature, common_.vars_, mapnik::color(128,128,128));
double opacity = get<double>(sym, keys::fill_opacity, feature, 1.0); double opacity = get<double>(sym, keys::fill_opacity, feature, common_.vars_, 1.0);
double height = get<double>(sym, keys::height, feature, 0.0); double height = get<double>(sym, keys::height, feature, common_.vars_, 0.0);
context_.set_operator(comp_op); context_.set_operator(comp_op);
@ -340,21 +344,19 @@ void cairo_renderer_base::process(line_symbolizer const& sym,
offset_transform_tag, offset_transform_tag,
dash_tag, stroke_tag> conv_types; dash_tag, stroke_tag> conv_types;
cairo_save_restore guard(context_); cairo_save_restore guard(context_);
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, src_over); composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, common_.vars_, src_over);
auto geom_transform = get_optional<transform_type>(sym, keys::geometry_transform); bool clip = get<bool>(sym, keys::clip, feature, common_.vars_, true);
bool clip = get<bool>(sym, keys::clip, feature, true); double offset = get<double>(sym, keys::offset, feature, common_.vars_, 0.0);
double offset = get<double>(sym, keys::offset, feature, 0.0); double simplify_tolerance = get<double>(sym, keys::simplify_tolerance, feature, common_.vars_, 0.0);
double simplify_tolerance = get<double>(sym, keys::simplify_tolerance, feature, 0.0); double smooth = get<double>(sym, keys::smooth, feature, common_.vars_, 0.0);
double smooth = get<double>(sym, keys::smooth, feature, 0.0);
mapnik::color stroke = get<mapnik::color>(sym, keys::stroke, feature, mapnik::color(0,0,0)); mapnik::color stroke = get<mapnik::color>(sym, keys::stroke, feature, common_.vars_, mapnik::color(0,0,0));
double stroke_opacity = get<double>(sym, keys::stroke_opacity, feature, 1.0); double stroke_opacity = get<double>(sym, keys::stroke_opacity, feature, common_.vars_, 1.0);
line_join_enum stroke_join = get<line_join_enum>(sym, keys::stroke_linejoin, MITER_JOIN); line_join_enum stroke_join = get<line_join_enum>(sym, keys::stroke_linejoin, feature, common_.vars_, MITER_JOIN);
line_cap_enum stroke_cap = get<line_cap_enum>(sym, keys::stroke_linecap, BUTT_CAP); line_cap_enum stroke_cap = get<line_cap_enum>(sym, keys::stroke_linecap, feature, common_.vars_, BUTT_CAP);
auto dash = get_optional<dash_array>(sym, keys::stroke_dasharray); auto dash = get_optional<dash_array>(sym, keys::stroke_dasharray);
double miterlimit = get<double>(sym, keys::stroke_miterlimit, feature, 4.0); double miterlimit = get<double>(sym, keys::stroke_miterlimit, feature, common_.vars_, 4.0);
double width = get<double>(sym, keys::stroke_width, feature, 1.0); double width = get<double>(sym, keys::stroke_width, feature, common_.vars_, 1.0);
context_.set_operator(comp_op); context_.set_operator(comp_op);
context_.set_color(stroke, stroke_opacity); context_.set_color(stroke, stroke_opacity);
@ -368,7 +370,8 @@ void cairo_renderer_base::process(line_symbolizer const& sym,
} }
agg::trans_affine tr; agg::trans_affine tr;
if (geom_transform) { evaluate_transform(tr, feature, *geom_transform, common_.scale_factor_); } auto geom_transform = get_optional<transform_type>(sym, keys::geometry_transform);
if (geom_transform) { evaluate_transform(tr, feature, common_.vars_, *geom_transform, common_.scale_factor_); }
box2d<double> clipping_extent = common_.query_extent_; box2d<double> clipping_extent = common_.query_extent_;
if (clip) if (clip)
@ -384,7 +387,7 @@ void cairo_renderer_base::process(line_symbolizer const& sym,
} }
vertex_converter<box2d<double>, cairo_context, line_symbolizer, vertex_converter<box2d<double>, cairo_context, line_symbolizer,
CoordTransform, proj_transform, agg::trans_affine, conv_types, feature_impl> CoordTransform, proj_transform, agg::trans_affine, conv_types, feature_impl>
converter(clipping_extent,context_,sym,common_.t_,prj_trans,tr,feature,common_.scale_factor_); converter(clipping_extent,context_,sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_);
if (clip) converter.set<clip_line_tag>(); // optional clip (default: true) if (clip) converter.set<clip_line_tag>(); // optional clip (default: true)
converter.set<transform_tag>(); // always transform converter.set<transform_tag>(); // always transform
@ -553,7 +556,7 @@ void cairo_renderer_base::process(point_symbolizer const& sym,
mapnik::feature_impl & feature, mapnik::feature_impl & feature,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, src_over); composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, common_.vars_, src_over);
cairo_save_restore guard(context_); cairo_save_restore guard(context_);
context_.set_operator(comp_op); context_.set_operator(comp_op);
@ -571,15 +574,15 @@ void cairo_renderer_base::process(shield_symbolizer const& sym,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
text_symbolizer_helper helper( text_symbolizer_helper helper(
sym, feature, prj_trans, sym, feature, common_.vars_, prj_trans,
common_.width_, common_.height_, common_.width_, common_.height_,
common_.scale_factor_, common_.scale_factor_,
common_.t_, common_.font_manager_, *common_.detector_, common_.t_, common_.font_manager_, *common_.detector_,
common_.query_extent_); common_.query_extent_);
cairo_save_restore guard(context_); cairo_save_restore guard(context_);
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, src_over); composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, common_.vars_, src_over);
double opacity = get<double>(sym,keys::opacity,feature, 1.0); double opacity = get<double>(sym,keys::opacity,feature, common_.vars_, 1.0);
context_.set_operator(comp_op); context_.set_operator(comp_op);
@ -605,8 +608,8 @@ void cairo_renderer_base::process(line_pattern_symbolizer const& sym,
typedef agg::conv_clip_polyline<geometry_type> clipped_geometry_type; typedef agg::conv_clip_polyline<geometry_type> clipped_geometry_type;
typedef coord_transform<CoordTransform,clipped_geometry_type> path_type; typedef coord_transform<CoordTransform,clipped_geometry_type> path_type;
std::string filename = get<std::string>(sym, keys::file, feature); std::string filename = get<std::string>(sym, keys::file, feature, common_.vars_);
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, src_over); composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, common_.vars_, src_over);
boost::optional<marker_ptr> marker; boost::optional<marker_ptr> marker;
if ( !filename.empty() ) if ( !filename.empty() )
@ -690,12 +693,11 @@ void cairo_renderer_base::process(polygon_pattern_symbolizer const& sym,
//typedef coord_transform<CoordTransform,clipped_geometry_type> path_type; //typedef coord_transform<CoordTransform,clipped_geometry_type> path_type;
cairo_save_restore guard(context_); cairo_save_restore guard(context_);
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, src_over); composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, common_.vars_, src_over);
std::string filename = get<std::string>(sym, keys::file, feature); std::string filename = get<std::string>(sym, keys::file, feature, common_.vars_);
auto geom_transform = get_optional<transform_type>(sym, keys::geometry_transform); bool clip = get<bool>(sym, keys::clip, feature, common_.vars_, true);
bool clip = get<bool>(sym, keys::clip, feature, false); double simplify_tolerance = get<double>(sym, keys::simplify_tolerance, feature, common_.vars_, 0.0);
double simplify_tolerance = get<double>(sym, keys::simplify_tolerance, feature, 0.0); double smooth = get<double>(sym, keys::smooth, feature, common_.vars_, 0.0);
double smooth = get<double>(sym, keys::smooth, feature, 0.0);
context_.set_operator(comp_op); context_.set_operator(comp_op);
@ -728,12 +730,13 @@ void cairo_renderer_base::process(polygon_pattern_symbolizer const& sym,
//} //}
agg::trans_affine tr; agg::trans_affine tr;
if (geom_transform) { evaluate_transform(tr, feature, *geom_transform, common_.scale_factor_); } auto geom_transform = get_optional<transform_type>(sym, keys::geometry_transform);
if (geom_transform) { evaluate_transform(tr, feature, common_.vars_, *geom_transform, common_.scale_factor_); }
typedef boost::mpl::vector<clip_poly_tag,transform_tag,affine_transform_tag,simplify_tag,smooth_tag> conv_types; typedef boost::mpl::vector<clip_poly_tag,transform_tag,affine_transform_tag,simplify_tag,smooth_tag> conv_types;
vertex_converter<box2d<double>, cairo_context, polygon_pattern_symbolizer, vertex_converter<box2d<double>, cairo_context, polygon_pattern_symbolizer,
CoordTransform, proj_transform, agg::trans_affine, conv_types, feature_impl> CoordTransform, proj_transform, agg::trans_affine, conv_types, feature_impl>
converter(common_.query_extent_,context_,sym,common_.t_,prj_trans,tr,feature,common_.scale_factor_); converter(common_.query_extent_,context_,sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_);
if (prj_trans.equal() && clip) converter.set<clip_poly_tag>(); //optional clip (default: true) if (prj_trans.equal() && clip) converter.set<clip_poly_tag>(); //optional clip (default: true)
converter.set<transform_tag>(); //always transform converter.set<transform_tag>(); //always transform
@ -758,14 +761,14 @@ void cairo_renderer_base::process(raster_symbolizer const& sym,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
cairo_save_restore guard(context_); cairo_save_restore guard(context_);
render_raster_symbolizer( render_raster_symbolizer(
sym, feature, prj_trans, common_, sym, feature, prj_trans, common_,
[&](raster &target, composite_mode_e comp_op, double opacity, [&](image_data_32 &target, composite_mode_e comp_op, double opacity,
int start_x, int start_y) { int start_x, int start_y) {
context_.set_operator(comp_op); context_.set_operator(comp_op);
context_.add_image(start_x, start_y, target.data_, opacity); context_.add_image(start_x, start_y, target, opacity);
}); }
);
} }
namespace detail { namespace detail {
@ -780,6 +783,8 @@ struct markers_dispatch
markers_symbolizer const& sym, markers_symbolizer const& sym,
box2d<double> const& bbox, box2d<double> const& bbox,
agg::trans_affine const& marker_trans, agg::trans_affine const& marker_trans,
feature_impl const& feature,
mapnik::attributes const& vars,
double scale_factor) double scale_factor)
:ctx_(ctx), :ctx_(ctx),
marker_(marker), marker_(marker),
@ -788,19 +793,20 @@ struct markers_dispatch
sym_(sym), sym_(sym),
bbox_(bbox), bbox_(bbox),
marker_trans_(marker_trans), marker_trans_(marker_trans),
feature_(feature),
vars_(vars),
scale_factor_(scale_factor) {} scale_factor_(scale_factor) {}
template <typename T> template <typename T>
void add_path(T & path) void add_path(T & path)
{ {
marker_placement_enum placement_method = get<marker_placement_enum>(sym_, keys::markers_placement_type, MARKER_POINT_PLACEMENT); marker_placement_enum placement_method = get<marker_placement_enum>(sym_, keys::markers_placement_type, feature_, vars_, MARKER_POINT_PLACEMENT);
bool ignore_placement = get<bool>(sym_, keys::ignore_placement, false); bool ignore_placement = get<bool>(sym_, keys::ignore_placement, feature_, vars_, false);
bool allow_overlap = get<bool>(sym_, keys::allow_overlap, false); bool allow_overlap = get<bool>(sym_, keys::allow_overlap, feature_, vars_, false);
double opacity = get<double>(sym_, keys::opacity, 1.0); double opacity = get<double>(sym_, keys::opacity, feature_, vars_, 1.0);
double spacing = get<double>(sym_, keys::spacing, feature_, vars_, 100.0);
double spacing = get<double>(sym_, keys::spacing, 100.0); double max_error = get<double>(sym_, keys::max_error, feature_, vars_, 0.2);
double max_error = get<double>(sym_, keys::max_error, 0.2);
if (placement_method != MARKER_LINE_PLACEMENT || if (placement_method != MARKER_LINE_PLACEMENT ||
path.type() == geometry_type::types::Point) path.type() == geometry_type::types::Point)
@ -864,6 +870,8 @@ struct markers_dispatch
markers_symbolizer const& sym_; markers_symbolizer const& sym_;
box2d<double> const& bbox_; box2d<double> const& bbox_;
agg::trans_affine const& marker_trans_; agg::trans_affine const& marker_trans_;
feature_impl const& feature_;
attributes const& vars_;
double scale_factor_; double scale_factor_;
}; };
@ -876,6 +884,8 @@ struct markers_dispatch_2
markers_symbolizer const& sym, markers_symbolizer const& sym,
box2d<double> const& bbox, box2d<double> const& bbox,
agg::trans_affine const& marker_trans, agg::trans_affine const& marker_trans,
feature_impl const& feature,
mapnik::attributes const& vars,
double scale_factor) double scale_factor)
:ctx_(ctx), :ctx_(ctx),
marker_(marker), marker_(marker),
@ -883,18 +893,20 @@ struct markers_dispatch_2
sym_(sym), sym_(sym),
bbox_(bbox), bbox_(bbox),
marker_trans_(marker_trans), marker_trans_(marker_trans),
feature_(feature),
vars_(vars),
scale_factor_(scale_factor) {} scale_factor_(scale_factor) {}
template <typename T> template <typename T>
void add_path(T & path) void add_path(T & path)
{ {
marker_placement_enum placement_method = get<marker_placement_enum>(sym_, keys::markers_placement_type, MARKER_POINT_PLACEMENT); marker_placement_enum placement_method = get<marker_placement_enum>(sym_, keys::markers_placement_type, feature_, vars_, MARKER_POINT_PLACEMENT);
double opacity = get<double>(sym_, keys::opacity, 1.0); double opacity = get<double>(sym_, keys::opacity, feature_, vars_, 1.0);
double spacing = get<double>(sym_, keys::spacing, 100.0); double spacing = get<double>(sym_, keys::spacing, feature_, vars_, 100.0);
double max_error = get<double>(sym_, keys::max_error, 0.2); double max_error = get<double>(sym_, keys::max_error, feature_, vars_, 0.2);
bool allow_overlap = get<bool>(sym_, keys::allow_overlap, false); bool allow_overlap = get<bool>(sym_, keys::allow_overlap, feature_, vars_, false);
bool ignore_placement = get<bool>(sym_, keys::ignore_placement, false); bool ignore_placement = get<bool>(sym_, keys::ignore_placement, feature_, vars_, false);
if (placement_method != MARKER_LINE_PLACEMENT || if (placement_method != MARKER_LINE_PLACEMENT ||
path.type() == geometry_type::types::Point) path.type() == geometry_type::types::Point)
@ -958,6 +970,8 @@ struct markers_dispatch_2
markers_symbolizer const& sym_; markers_symbolizer const& sym_;
box2d<double> const& bbox_; box2d<double> const& bbox_;
agg::trans_affine const& marker_trans_; agg::trans_affine const& marker_trans_;
feature_impl const& feature_;
attributes const& vars_;
double scale_factor_; double scale_factor_;
}; };
@ -973,7 +987,7 @@ void cairo_renderer_base::process(markers_symbolizer const& sym,
label_collision_detector4> vector_dispatch_type; label_collision_detector4> vector_dispatch_type;
cairo_save_restore guard(context_); cairo_save_restore guard(context_);
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, src_over); composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, common_.vars_, src_over);
context_.set_operator(comp_op); context_.set_operator(comp_op);
box2d<double> clip_box = common_.query_extent_; box2d<double> clip_box = common_.query_extent_;
@ -983,12 +997,12 @@ void cairo_renderer_base::process(markers_symbolizer const& sym,
box2d<double> const &bbox, agg::trans_affine const &marker_trans, box2d<double> const &bbox, agg::trans_affine const &marker_trans,
bool) -> vector_dispatch_type { bool) -> vector_dispatch_type {
return vector_dispatch_type(context_, marker, attr, *common_.detector_, sym, bbox, return vector_dispatch_type(context_, marker, attr, *common_.detector_, sym, bbox,
marker_trans, common_.scale_factor_); marker_trans, feature, common_.vars_, common_.scale_factor_);
}, },
[&](image_data_32 &marker, agg::trans_affine const &marker_trans, [&](image_data_32 &marker, agg::trans_affine const &marker_trans,
box2d<double> const &bbox) -> raster_dispatch_type { box2d<double> const &bbox) -> raster_dispatch_type {
return raster_dispatch_type(context_, marker, *common_.detector_, sym, bbox, return raster_dispatch_type(context_, marker, *common_.detector_, sym, bbox,
marker_trans, common_.scale_factor_); marker_trans, feature, common_.vars_, common_.scale_factor_);
}); });
} }
@ -997,15 +1011,14 @@ void cairo_renderer_base::process(text_symbolizer const& sym,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
text_symbolizer_helper helper( text_symbolizer_helper helper(
sym, feature, prj_trans, sym, feature, common_.vars_, prj_trans,
common_.width_, common_.height_, common_.width_, common_.height_,
common_.scale_factor_, common_.scale_factor_,
common_.t_, common_.font_manager_, *common_.detector_, common_.t_, common_.font_manager_, *common_.detector_,
common_.query_extent_); common_.query_extent_);
cairo_save_restore guard(context_); cairo_save_restore guard(context_);
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, src_over); composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, common_.vars_, src_over);
context_.set_operator(comp_op); context_.set_operator(comp_op);
placements_list const &placements = helper.get(); placements_list const &placements = helper.get();
@ -1085,7 +1098,7 @@ void cairo_renderer_base::process(group_symbolizer const& sym,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
render_group_symbolizer( render_group_symbolizer(
sym, feature, prj_trans, common_.query_extent_, common_, sym, feature, common_.vars_, prj_trans, common_.query_extent_, common_,
[&](render_thunk_list const& thunks, pixel_position const& render_offset) [&](render_thunk_list const& thunks, pixel_position const& render_offset)
{ {
thunk_renderer ren(*this, context_, face_manager_, common_, render_offset); thunk_renderer ren(*this, context_, face_manager_, common_, render_offset);
@ -1123,7 +1136,7 @@ void cairo_renderer_base::process(debug_symbolizer const& sym,
typedef label_collision_detector4 detector_type; typedef label_collision_detector4 detector_type;
cairo_save_restore guard(context_); cairo_save_restore guard(context_);
debug_symbolizer_mode_enum mode = get<debug_symbolizer_mode_enum>(sym, keys::mode, DEBUG_SYM_MODE_COLLISION); debug_symbolizer_mode_enum mode = get<debug_symbolizer_mode_enum>(sym, keys::mode, feature, common_.vars_, DEBUG_SYM_MODE_COLLISION);
context_.set_operator(src_over); context_.set_operator(src_over);
context_.set_color(mapnik::color(255, 0, 0), 1.0); context_.set_color(mapnik::color(255, 0, 0), 1.0);

View file

@ -63,19 +63,19 @@ grid_renderer<T>::grid_renderer(Map const& m, T & pixmap, double scale_factor, u
ras_ptr(new grid_rasterizer), ras_ptr(new grid_rasterizer),
// NOTE: can change this to m dims instead of pixmap_ if render-time // NOTE: can change this to m dims instead of pixmap_ if render-time
// resolution support is dropped from grid_renderer python interface // resolution support is dropped from grid_renderer python interface
common_(m, offset_x, offset_y, pixmap_.width(), pixmap_.height(), scale_factor) common_(m, attributes(), offset_x, offset_y, pixmap_.width(), pixmap_.height(), scale_factor)
{ {
setup(m); setup(m);
} }
template <typename T> 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) grid_renderer<T>::grid_renderer(Map const& m, request const& req, attributes const& vars, T & pixmap, double scale_factor, unsigned offset_x, unsigned offset_y)
: feature_style_processor<grid_renderer>(m, scale_factor), : feature_style_processor<grid_renderer>(m, scale_factor),
pixmap_(pixmap), pixmap_(pixmap),
ras_ptr(new grid_rasterizer), ras_ptr(new grid_rasterizer),
// NOTE: can change this to m dims instead of pixmap_ if render-time // NOTE: can change this to m dims instead of pixmap_ if render-time
// resolution support is dropped from grid_renderer python interface // resolution support is dropped from grid_renderer python interface
common_(req, offset_x, offset_y, pixmap_.width(), pixmap_.height(), scale_factor) common_(req, vars, offset_x, offset_y, pixmap_.width(), pixmap_.height(), scale_factor)
{ {
setup(m); setup(m);
} }

View file

@ -68,7 +68,7 @@ void grid_renderer<T>::process(building_symbolizer const& sym,
ras_ptr->reset(); ras_ptr->reset();
double height = get<value_double>(sym, keys::height,feature, 0.0); double height = get<value_double>(sym, keys::height, feature, common_.vars_, 0.0);
render_building_symbolizer( render_building_symbolizer(
feature, height, feature, height,

View file

@ -117,7 +117,7 @@ void grid_renderer<T>::process(group_symbolizer const& sym,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
render_group_symbolizer( render_group_symbolizer(
sym, feature, prj_trans, common_.query_extent_, common_, sym, feature, common_.vars_, prj_trans, common_.query_extent_, common_,
[&](render_thunk_list const& thunks, pixel_position const& render_offset) [&](render_thunk_list const& thunks, pixel_position const& render_offset)
{ {
thunk_renderer<T> ren(*this, pixmap_, common_, feature, render_offset); thunk_renderer<T> ren(*this, pixmap_, common_, feature, render_offset);

View file

@ -50,9 +50,9 @@ void grid_renderer<T>::process(line_pattern_symbolizer const& sym,
mapnik::feature_impl & feature, mapnik::feature_impl & feature,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
std::string filename = get<std::string>(sym, keys::file, feature); std::string filename = get<std::string>(sym, keys::file, feature, common_.vars_);
if (filename.empty()) return;
boost::optional<marker_ptr> mark = marker_cache::instance().find(filename,true); boost::optional<mapnik::marker_ptr> mark = marker_cache::instance().find(filename, true);
if (!mark) return; if (!mark) return;
if (!(*mark)->is_bitmap()) if (!(*mark)->is_bitmap())
@ -64,10 +64,10 @@ void grid_renderer<T>::process(line_pattern_symbolizer const& sym,
boost::optional<image_ptr> pat = (*mark)->get_bitmap_data(); boost::optional<image_ptr> pat = (*mark)->get_bitmap_data();
if (!pat) return; if (!pat) return;
bool clip = get<value_bool>(sym, keys::clip, feature); bool clip = get<value_bool>(sym, keys::clip, feature, common_.vars_, true);
double offset = get<value_double>(sym, keys::offset, feature, 0.0); double offset = get<value_double>(sym, keys::offset, feature, common_.vars_, 0.0);
double simplify_tolerance = get<value_double>(sym, keys::simplify_tolerance, feature, 0.0); double simplify_tolerance = get<value_double>(sym, keys::simplify_tolerance, feature, common_.vars_, 0.0);
double smooth = get<value_double>(sym, keys::smooth, feature, false); double smooth = get<value_double>(sym, keys::smooth, feature, common_.vars_, false);
typedef typename grid_renderer_base_type::pixfmt_type pixfmt_type; typedef typename grid_renderer_base_type::pixfmt_type pixfmt_type;
typedef typename grid_renderer_base_type::pixfmt_type::color_type color_type; typedef typename grid_renderer_base_type::pixfmt_type::color_type color_type;
@ -89,7 +89,10 @@ void grid_renderer<T>::process(line_pattern_symbolizer const& sym,
agg::trans_affine tr; agg::trans_affine tr;
auto transform = get_optional<transform_type>(sym, keys::geometry_transform); auto transform = get_optional<transform_type>(sym, keys::geometry_transform);
if (transform) { evaluate_transform(tr, feature, *transform, common_.scale_factor_); } if (transform)
{
evaluate_transform(tr, feature, common_.vars_, *transform, common_.scale_factor_);
}
box2d<double> clipping_extent = common_.query_extent_; box2d<double> clipping_extent = common_.query_extent_;
if (clip) if (clip)
@ -117,7 +120,7 @@ void grid_renderer<T>::process(line_pattern_symbolizer const& sym,
vertex_converter<box2d<double>, grid_rasterizer, line_symbolizer, vertex_converter<box2d<double>, grid_rasterizer, line_symbolizer,
CoordTransform, proj_transform, agg::trans_affine, conv_types, feature_impl> CoordTransform, proj_transform, agg::trans_affine, conv_types, feature_impl>
converter(clipping_extent,*ras_ptr,line,common_.t_,prj_trans,tr,feature,common_.scale_factor_); converter(clipping_extent,*ras_ptr,line,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_);
if (clip) converter.set<clip_line_tag>(); // optional clip (default: true) if (clip) converter.set<clip_line_tag>(); // optional clip (default: true)
converter.set<transform_tag>(); // always transform converter.set<transform_tag>(); // always transform
if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset

View file

@ -65,15 +65,18 @@ void grid_renderer<T>::process(line_symbolizer const& sym,
agg::trans_affine tr; agg::trans_affine tr;
auto transform = get_optional<transform_type>(sym, keys::geometry_transform); auto transform = get_optional<transform_type>(sym, keys::geometry_transform);
if (transform) { evaluate_transform(tr, feature, *transform, common_.scale_factor_); } if (transform)
{
evaluate_transform(tr, feature, common_.vars_, *transform, common_.scale_factor_);
}
box2d<double> clipping_extent = common_.query_extent_; box2d<double> clipping_extent = common_.query_extent_;
bool clip = get<value_bool>(sym, keys::clip, feature, true); bool clip = get<value_bool>(sym, keys::clip, feature, common_.vars_, true);
double width = get<value_double>(sym, keys::stroke_width, feature, 1.0); double width = get<value_double>(sym, keys::stroke_width, feature, common_.vars_,1.0);
double offset = get<value_double>(sym, keys::offset, feature, 0.0); double offset = get<value_double>(sym, keys::offset, feature, common_.vars_,0.0);
double simplify_tolerance = get<value_double>(sym, keys::simplify_tolerance, feature, 0.0); double simplify_tolerance = get<value_double>(sym, keys::simplify_tolerance, feature, common_.vars_,0.0);
double smooth = get<value_double>(sym, keys::smooth, feature, false); double smooth = get<value_double>(sym, keys::smooth, feature, common_.vars_,false);
bool has_dash = has_key<dash_array>(sym, keys::stroke_dasharray); bool has_dash = has_key<dash_array>(sym, keys::stroke_dasharray);
if (clip) if (clip)
@ -90,7 +93,7 @@ void grid_renderer<T>::process(line_symbolizer const& sym,
vertex_converter<box2d<double>, grid_rasterizer, line_symbolizer, vertex_converter<box2d<double>, grid_rasterizer, line_symbolizer,
CoordTransform, proj_transform, agg::trans_affine, conv_types, feature_impl> CoordTransform, proj_transform, agg::trans_affine, conv_types, feature_impl>
converter(clipping_extent,*ras_ptr,sym,common_.t_,prj_trans,tr,feature,common_.scale_factor_); converter(clipping_extent,*ras_ptr,sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_);
if (clip) converter.set<clip_line_tag>(); // optional clip (default: true) if (clip) converter.set<clip_line_tag>(); // optional clip (default: true)
converter.set<transform_tag>(); // always transform converter.set<transform_tag>(); // always transform
if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset

View file

@ -129,6 +129,7 @@ void grid_renderer<T>::process(markers_symbolizer const& sym,
*common_.detector_, *common_.detector_,
common_.scale_factor_, common_.scale_factor_,
feature, feature,
common_.vars_,
pixmap_); pixmap_);
}, },
[&](image_data_32 const &marker, agg::trans_affine const &tr, [&](image_data_32 const &marker, agg::trans_affine const &tr,
@ -145,6 +146,7 @@ void grid_renderer<T>::process(markers_symbolizer const& sym,
*common_.detector_, *common_.detector_,
common_.scale_factor_, common_.scale_factor_,
feature, feature,
common_.vars_,
pixmap_); pixmap_);
}); });
} }

View file

@ -52,7 +52,7 @@ void grid_renderer<T>::process(point_symbolizer const& sym,
mapnik::feature_impl & feature, mapnik::feature_impl & feature,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, src_over); composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, common_.vars_, src_over);
render_point_symbolizer( render_point_symbolizer(
sym, feature, prj_trans, common_, sym, feature, prj_trans, common_,

View file

@ -52,9 +52,9 @@ void grid_renderer<T>::process(polygon_pattern_symbolizer const& sym,
mapnik::feature_impl & feature, mapnik::feature_impl & feature,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
std::string filename = get<std::string>(sym, keys::file, feature); std::string filename = get<std::string>(sym, keys::file, feature, common_.vars_);
if (filename.empty()) return;
boost::optional<marker_ptr> mark = marker_cache::instance().find(filename,true); boost::optional<mapnik::marker_ptr> mark = marker_cache::instance().find(filename, true);
if (!mark) return; if (!mark) return;
if (!(*mark)->is_bitmap()) if (!(*mark)->is_bitmap())
@ -68,18 +68,21 @@ void grid_renderer<T>::process(polygon_pattern_symbolizer const& sym,
ras_ptr->reset(); ras_ptr->reset();
bool clip = get<value_bool>(sym, keys::clip, feature, false); bool clip = get<value_bool>(sym, keys::clip, feature, common_.vars_, true);
double simplify_tolerance = get<value_double>(sym, keys::simplify_tolerance, feature, 0.0); double simplify_tolerance = get<value_double>(sym, keys::simplify_tolerance, feature, common_.vars_, 0.0);
double smooth = get<value_double>(sym, keys::smooth, feature, false); double smooth = get<value_double>(sym, keys::smooth, feature, common_.vars_, false);
agg::trans_affine tr; agg::trans_affine tr;
auto geom_transform = get_optional<transform_type>(sym, keys::geometry_transform); auto transform = get_optional<transform_type>(sym, keys::geometry_transform);
if (geom_transform) evaluate_transform(tr, feature, *geom_transform, common_.scale_factor_); if (transform)
{
evaluate_transform(tr, feature, common_.vars_, *transform, common_.scale_factor_);
}
typedef boost::mpl::vector<clip_poly_tag,transform_tag,affine_transform_tag,smooth_tag> conv_types; typedef boost::mpl::vector<clip_poly_tag,transform_tag,affine_transform_tag,smooth_tag> conv_types;
vertex_converter<box2d<double>, grid_rasterizer, polygon_pattern_symbolizer, vertex_converter<box2d<double>, grid_rasterizer, polygon_pattern_symbolizer,
CoordTransform, proj_transform, agg::trans_affine, conv_types, feature_impl> CoordTransform, proj_transform, agg::trans_affine, conv_types, feature_impl>
converter(common_.query_extent_,*ras_ptr,sym,common_.t_,prj_trans,tr,feature,common_.scale_factor_); converter(common_.query_extent_,*ras_ptr,sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_);
if (prj_trans.equal() && clip) converter.set<clip_poly_tag>(); //optional clip (default: true) if (prj_trans.equal() && clip) converter.set<clip_poly_tag>(); //optional clip (default: true)
converter.set<transform_tag>(); //always transform converter.set<transform_tag>(); //always transform

View file

@ -44,15 +44,15 @@ void grid_renderer<T>::process(shield_symbolizer const& sym,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
text_symbolizer_helper helper( text_symbolizer_helper helper(
sym, feature, prj_trans, sym, feature, common_.vars_, prj_trans,
common_.width_, common_.height_, common_.width_, common_.height_,
common_.scale_factor_, common_.scale_factor_,
common_.t_, common_.font_manager_, *common_.detector_, common_.t_, common_.font_manager_, *common_.detector_,
common_.query_extent_); common_.query_extent_);
bool placement_found = false; bool placement_found = false;
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, src_over); composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, common_.vars_, src_over);
double opacity = get<double>(sym,keys::opacity,feature, 1.0); double opacity = get<double>(sym, keys::opacity, feature, common_.vars_, 1.0);
grid_text_renderer<T> ren(pixmap_, grid_text_renderer<T> ren(pixmap_,
comp_op, comp_op,

View file

@ -37,14 +37,14 @@ void grid_renderer<T>::process(text_symbolizer const& sym,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
text_symbolizer_helper helper( text_symbolizer_helper helper(
sym, feature, prj_trans, sym, feature, common_.vars_, prj_trans,
common_.width_, common_.height_, common_.width_, common_.height_,
common_.scale_factor_ * (1.0/pixmap_.get_resolution()), common_.scale_factor_ * (1.0/pixmap_.get_resolution()),
common_.t_, common_.font_manager_, *common_.detector_, common_.t_, common_.font_manager_, *common_.detector_,
common_.query_extent_); common_.query_extent_);
bool placement_found = false; bool placement_found = false;
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, src_over); composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, common_.vars_, src_over);
grid_text_renderer<T> ren(pixmap_, grid_text_renderer<T> ren(pixmap_,
comp_op, comp_op,

View file

@ -39,11 +39,12 @@ namespace mapnik {
group_symbolizer_helper::group_symbolizer_helper( group_symbolizer_helper::group_symbolizer_helper(
const group_symbolizer &sym, const feature_impl &feature, const group_symbolizer &sym, const feature_impl &feature,
attributes const& vars,
const proj_transform &prj_trans, const proj_transform &prj_trans,
unsigned width, unsigned height, double scale_factor, unsigned width, unsigned height, double scale_factor,
const CoordTransform &t, DetectorType &detector, const CoordTransform &t, DetectorType &detector,
const box2d<double> &query_extent) const box2d<double> &query_extent)
: base_symbolizer_helper(sym, feature, prj_trans, width, height, scale_factor, t, query_extent), : base_symbolizer_helper(sym, feature, vars, prj_trans, width, height, scale_factor, t, query_extent),
detector_(detector) detector_(detector)
{} {}

View file

@ -24,14 +24,18 @@
#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/request.hpp>
#include <mapnik/attribute.hpp>
namespace mapnik { namespace mapnik {
renderer_common::renderer_common(unsigned width, unsigned height, double scale_factor, renderer_common::renderer_common(unsigned width, unsigned height, double scale_factor,
CoordTransform &&t, std::shared_ptr<label_collision_detector4> detector) attributes const& vars,
CoordTransform && t,
std::shared_ptr<label_collision_detector4> detector)
: width_(width), : width_(width),
height_(height), height_(height),
scale_factor_(scale_factor), scale_factor_(scale_factor),
vars_(vars),
shared_font_engine_(std::make_shared<freetype_engine>()), shared_font_engine_(std::make_shared<freetype_engine>()),
font_engine_(*shared_font_engine_), font_engine_(*shared_font_engine_),
font_manager_(font_engine_), font_manager_(font_engine_),
@ -40,26 +44,29 @@ renderer_common::renderer_common(unsigned width, unsigned height, double scale_f
detector_(detector) detector_(detector)
{} {}
renderer_common::renderer_common(Map const &m, unsigned offset_x, unsigned offset_y, renderer_common::renderer_common(Map const &m, attributes const& vars, unsigned offset_x, unsigned offset_y,
unsigned width, unsigned height, double scale_factor) unsigned width, unsigned height, double scale_factor)
: renderer_common(width, height, scale_factor, : renderer_common(width, height, scale_factor,
vars,
CoordTransform(m.width(),m.height(),m.get_current_extent(),offset_x,offset_y), CoordTransform(m.width(),m.height(),m.get_current_extent(),offset_x,offset_y),
std::make_shared<label_collision_detector4>( std::make_shared<label_collision_detector4>(
box2d<double>(-m.buffer_size(), -m.buffer_size(), box2d<double>(-m.buffer_size(), -m.buffer_size(),
m.width() + m.buffer_size() ,m.height() + m.buffer_size()))) m.width() + m.buffer_size() ,m.height() + m.buffer_size())))
{} {}
renderer_common::renderer_common(Map const &m, unsigned offset_x, unsigned offset_y, renderer_common::renderer_common(Map const &m, attributes const& vars, unsigned offset_x, unsigned offset_y,
unsigned width, unsigned height, double scale_factor, unsigned width, unsigned height, double scale_factor,
std::shared_ptr<label_collision_detector4> detector) std::shared_ptr<label_collision_detector4> detector)
: renderer_common(width, height, scale_factor, : renderer_common(width, height, scale_factor,
vars,
CoordTransform(m.width(),m.height(),m.get_current_extent(),offset_x,offset_y), CoordTransform(m.width(),m.height(),m.get_current_extent(),offset_x,offset_y),
detector) detector)
{} {}
renderer_common::renderer_common(request const &req, unsigned offset_x, unsigned offset_y, renderer_common::renderer_common(request const &req, attributes const& vars, unsigned offset_x, unsigned offset_y,
unsigned width, unsigned height, double scale_factor) unsigned width, unsigned height, double scale_factor)
: renderer_common(width, height, scale_factor, : renderer_common(width, height, scale_factor,
vars,
CoordTransform(req.width(),req.height(),req.extent(),offset_x,offset_y), CoordTransform(req.width(),req.height(),req.extent(),offset_x,offset_y),
std::make_shared<label_collision_detector4>( std::make_shared<label_collision_detector4>(
box2d<double>(-req.buffer_size(), -req.buffer_size(), box2d<double>(-req.buffer_size(), -req.buffer_size(),
@ -70,6 +77,7 @@ renderer_common::renderer_common(renderer_common const &other)
: width_(other.width_), : width_(other.width_),
height_(other.height_), height_(other.height_),
scale_factor_(other.scale_factor_), scale_factor_(other.scale_factor_),
vars_(other.vars_),
shared_font_engine_(other.shared_font_engine_), shared_font_engine_(other.shared_font_engine_),
font_engine_(*shared_font_engine_), font_engine_(*shared_font_engine_),
font_manager_(font_engine_), font_manager_(font_engine_),

View file

@ -72,17 +72,18 @@ text_render_thunk::text_render_thunk(placements_list const &placements,
render_thunk_extractor::render_thunk_extractor(box2d<double> &box, render_thunk_extractor::render_thunk_extractor(box2d<double> &box,
render_thunk_list &thunks, render_thunk_list &thunks,
mapnik::feature_impl &feature, feature_impl &feature,
attributes const& vars,
proj_transform const &prj_trans, proj_transform const &prj_trans,
renderer_common &common, renderer_common &common,
box2d<double> const &clipping_extent) box2d<double> const &clipping_extent)
: box_(box), thunks_(thunks), feature_(feature), prj_trans_(prj_trans), : box_(box), thunks_(thunks), feature_(feature), vars_(vars), prj_trans_(prj_trans),
common_(common), clipping_extent_(clipping_extent) common_(common), clipping_extent_(clipping_extent)
{} {}
void render_thunk_extractor::operator()(point_symbolizer const &sym) const void render_thunk_extractor::operator()(point_symbolizer const &sym) const
{ {
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature_, src_over); composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature_, common_.vars_, src_over);
render_point_symbolizer( render_point_symbolizer(
sym, feature_, prj_trans_, common_, sym, feature_, prj_trans_, common_,
@ -99,7 +100,7 @@ void render_thunk_extractor::operator()(text_symbolizer const &sym) const
{ {
box2d<double> clip_box = clipping_extent_; box2d<double> clip_box = clipping_extent_;
text_symbolizer_helper helper( text_symbolizer_helper helper(
sym, feature_, prj_trans_, sym, feature_, vars_, prj_trans_,
common_.width_, common_.height_, common_.width_, common_.height_,
common_.scale_factor_, common_.scale_factor_,
common_.t_, common_.font_manager_, *common_.detector_, common_.t_, common_.font_manager_, *common_.detector_,
@ -112,7 +113,7 @@ void render_thunk_extractor::operator()(shield_symbolizer const &sym) const
{ {
box2d<double> clip_box = clipping_extent_; box2d<double> clip_box = clipping_extent_;
text_symbolizer_helper helper( text_symbolizer_helper helper(
sym, feature_, prj_trans_, sym, feature_, vars_, prj_trans_,
common_.width_, common_.height_, common_.width_, common_.height_,
common_.scale_factor_, common_.scale_factor_,
common_.t_, common_.font_manager_, *common_.detector_, common_.t_, common_.font_manager_, *common_.detector_,
@ -123,9 +124,9 @@ void render_thunk_extractor::operator()(shield_symbolizer const &sym) const
void render_thunk_extractor::extract_text_thunk(text_symbolizer_helper &helper, text_symbolizer const &sym) const void render_thunk_extractor::extract_text_thunk(text_symbolizer_helper &helper, text_symbolizer const &sym) const
{ {
double opacity = get<double>(sym, keys::opacity, feature_, 1.0); double opacity = get<double>(sym, keys::opacity, feature_, common_.vars_, 1.0);
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature_, src_over); composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature_, common_.vars_, src_over);
halo_rasterizer_enum halo_rasterizer = get<halo_rasterizer_enum>(sym, keys::halo_rasterizer, HALO_RASTERIZER_FULL); halo_rasterizer_enum halo_rasterizer = get<halo_rasterizer_enum>(sym, keys::halo_rasterizer, feature_, common_.vars_, HALO_RASTERIZER_FULL);
placements_list const& placements = helper.get(); placements_list const& placements = helper.get();
text_render_thunk thunk(placements, opacity, comp_op, halo_rasterizer); text_render_thunk thunk(placements, opacity, comp_op, halo_rasterizer);

View file

@ -42,16 +42,16 @@ svg_renderer<T>::svg_renderer(Map const& m, T & output_iterator, double scale_fa
output_iterator_(output_iterator), output_iterator_(output_iterator),
generator_(output_iterator), generator_(output_iterator),
painted_(false), painted_(false),
common_(m, offset_x, offset_y, m.width(), m.height(), scale_factor) common_(m, attributes(), offset_x, offset_y, m.width(), m.height(), scale_factor)
{} {}
template <typename T> template <typename T>
svg_renderer<T>::svg_renderer(Map const& m, request const& req, T & output_iterator, double scale_factor, unsigned offset_x, unsigned offset_y) : svg_renderer<T>::svg_renderer(Map const& m, request const& req, attributes const& vars, T & output_iterator, double scale_factor, unsigned offset_x, unsigned offset_y) :
feature_style_processor<svg_renderer>(m, scale_factor), feature_style_processor<svg_renderer>(m, scale_factor),
output_iterator_(output_iterator), output_iterator_(output_iterator),
generator_(output_iterator), generator_(output_iterator),
painted_(false), painted_(false),
common_(req, offset_x, offset_y, req.width(), req.height(), scale_factor) common_(req, vars, offset_x, offset_y, req.width(), req.height(), scale_factor)
{} {}
template <typename T> template <typename T>

View file

@ -29,7 +29,9 @@
namespace mapnik { namespace mapnik {
// START FIXME - move to its own compilation unit // START FIXME - move to its own compilation unit
void evaluate_transform(agg::trans_affine& tr, feature_impl const& feature, void evaluate_transform(agg::trans_affine& tr,
feature_impl const& feature,
attributes const& vars,
transform_list_ptr const& trans_expr, double scale_factor) transform_list_ptr const& trans_expr, double scale_factor)
{ {
if (trans_expr) if (trans_expr)
@ -38,7 +40,7 @@ void evaluate_transform(agg::trans_affine& tr, feature_impl const& feature,
MAPNIK_LOG_DEBUG(transform) << "transform: evaluate " MAPNIK_LOG_DEBUG(transform) << "transform: evaluate "
<< transform_processor_type::to_string(*trans_expr); << transform_processor_type::to_string(*trans_expr);
#endif #endif
transform_processor_type::evaluate(tr, feature, *trans_expr, scale_factor); transform_processor_type::evaluate(tr, feature, vars, *trans_expr, scale_factor);
} }
} }
// END FIXME // END FIXME

View file

@ -94,7 +94,9 @@ static const property_meta_type key_meta[to_integral(keys::MAX_SYMBOLIZER_KEY)]
property_meta_type{ "num-columns", static_cast<value_integer>(0), nullptr, property_types::target_integer}, property_meta_type{ "num-columns", static_cast<value_integer>(0), nullptr, property_types::target_integer},
property_meta_type{ "start-column", static_cast<value_integer>(1), nullptr, property_types::target_integer}, property_meta_type{ "start-column", static_cast<value_integer>(1), nullptr, property_types::target_integer},
property_meta_type{ "repeat-key", nullptr, nullptr, property_types::target_repeat_key}, property_meta_type{ "repeat-key", nullptr, nullptr, property_types::target_repeat_key},
property_meta_type{ "symbolizer-properties", nullptr, nullptr, property_types::target_group_symbolizer_properties} property_meta_type{ "symbolizer-properties", nullptr, nullptr, property_types::target_group_symbolizer_properties},
property_meta_type{ "largest-box-only", false, nullptr, property_types::target_bool },
property_meta_type{ "minimum-path-length", false, nullptr, property_types::target_double }
}; };
property_meta_type const& get_meta(mapnik::keys key) property_meta_type const& get_meta(mapnik::keys key)

View file

@ -32,10 +32,8 @@
#include <mapnik/xml_node.hpp> #include <mapnik/xml_node.hpp>
//boost //boost
#include <boost/property_tree/ptree.hpp> #include <boost/property_tree/ptree.hpp>
namespace mapnik { namespace mapnik {
namespace formatting { namespace formatting {
@ -82,31 +80,30 @@ expression_ptr expression_format::get_expression(xml_node const& xml, std::strin
return expression_ptr(); return expression_ptr();
} }
void expression_format::apply(char_properties_ptr p, feature_impl const& feature, attributes const& vars, text_layout &output) const
void expression_format::apply(char_properties_ptr p, feature_impl const& feature, text_layout &output) const
{ {
char_properties_ptr new_properties = std::make_shared<char_properties>(*p); char_properties_ptr new_properties = std::make_shared<char_properties>(*p);
if (face_name) new_properties->face_name = if (face_name) new_properties->face_name =
boost::apply_visitor(evaluate<feature_impl,value_type>(feature), *face_name).to_string(); boost::apply_visitor(evaluate<feature_impl,value_type,attributes>(feature,vars), *face_name).to_string();
if (text_size) new_properties->text_size = if (text_size) new_properties->text_size =
boost::apply_visitor(evaluate<feature_impl,value_type>(feature), *text_size).to_double(); boost::apply_visitor(evaluate<feature_impl,value_type,attributes>(feature,vars), *text_size).to_double();
if (character_spacing) new_properties->character_spacing = if (character_spacing) new_properties->character_spacing =
boost::apply_visitor(evaluate<feature_impl,value_type>(feature), *character_spacing).to_double(); boost::apply_visitor(evaluate<feature_impl,value_type,attributes>(feature,vars), *character_spacing).to_double();
if (line_spacing) new_properties->line_spacing = if (line_spacing) new_properties->line_spacing =
boost::apply_visitor(evaluate<feature_impl,value_type>(feature), *line_spacing).to_double(); boost::apply_visitor(evaluate<feature_impl,value_type,attributes>(feature,vars), *line_spacing).to_double();
if (text_opacity) new_properties->text_opacity = if (text_opacity) new_properties->text_opacity =
boost::apply_visitor(evaluate<feature_impl,value_type>(feature), *text_opacity).to_double(); boost::apply_visitor(evaluate<feature_impl,value_type,attributes>(feature,vars), *text_opacity).to_double();
if (wrap_char) new_properties->wrap_char = if (wrap_char) new_properties->wrap_char =
boost::apply_visitor(evaluate<feature_impl,value_type>(feature), *character_spacing).to_unicode()[0]; boost::apply_visitor(evaluate<feature_impl,value_type,attributes>(feature,vars), *character_spacing).to_unicode()[0];
if (fill) new_properties->fill = parse_color( if (fill) new_properties->fill = parse_color(
boost::apply_visitor(evaluate<feature_impl,value_type>(feature), *fill).to_string()); boost::apply_visitor(evaluate<feature_impl,value_type,attributes>(feature,vars), *fill).to_string());
if (halo_fill) new_properties->halo_fill = parse_color( if (halo_fill) new_properties->halo_fill = parse_color(
boost::apply_visitor(evaluate<feature_impl,value_type>(feature), *halo_fill).to_string()); boost::apply_visitor(evaluate<feature_impl,value_type,attributes>(feature,vars), *halo_fill).to_string());
if (halo_radius) new_properties->halo_radius = if (halo_radius) new_properties->halo_radius =
boost::apply_visitor(evaluate<feature_impl,value_type>(feature), *halo_radius).to_double(); boost::apply_visitor(evaluate<feature_impl,value_type,attributes>(feature,vars), *halo_radius).to_double();
if (child_) { if (child_) {
child_->apply(new_properties, feature, output); child_->apply(new_properties, feature, vars, output);
} else { } else {
MAPNIK_LOG_WARN(expression) << "Useless format: No text to format"; MAPNIK_LOG_WARN(expression) << "Useless format: No text to format";
} }

View file

@ -77,7 +77,7 @@ node_ptr format_node::from_xml(xml_node const& xml)
} }
void format_node::apply(char_properties_ptr p, const feature_impl &feature, text_layout &output) const void format_node::apply(char_properties_ptr p, feature_impl const& feature, attributes const& vars, text_layout &output) const
{ {
char_properties_ptr new_properties = std::make_shared<char_properties>(*p); char_properties_ptr new_properties = std::make_shared<char_properties>(*p);
if (face_name) new_properties->face_name = *face_name; if (face_name) new_properties->face_name = *face_name;
@ -92,7 +92,7 @@ void format_node::apply(char_properties_ptr p, const feature_impl &feature, text
if (halo_radius) new_properties->halo_radius = *halo_radius; if (halo_radius) new_properties->halo_radius = *halo_radius;
if (child_) { if (child_) {
child_->apply(new_properties, feature, output); child_->apply(new_properties, feature, vars, output);
} else { } else {
MAPNIK_LOG_WARN(format) << "Useless format: No text to format"; MAPNIK_LOG_WARN(format) << "Useless format: No text to format";
} }

View file

@ -79,7 +79,7 @@ node_ptr layout_node::from_xml(xml_node const& xml)
return n; return n;
} }
void layout_node::apply(char_properties_ptr p, feature_impl const& feature, text_layout &output) const void layout_node::apply(char_properties_ptr p, feature_impl const& feature, attributes const& vars, text_layout &output) const
{ {
text_layout_properties_ptr new_properties = std::make_shared<text_layout_properties>(*output.get_layout_properties()); text_layout_properties_ptr new_properties = std::make_shared<text_layout_properties>(*output.get_layout_properties());
if (dx) new_properties->displacement.x = *dx; if (dx) new_properties->displacement.x = *dx;
@ -95,11 +95,11 @@ void layout_node::apply(char_properties_ptr p, feature_impl const& feature, text
// starting a new offset child with the new displacement value // starting a new offset child with the new displacement value
text_layout_ptr child_layout = std::make_shared<text_layout>(output.get_font_manager(), output.get_scale_factor(), new_properties); text_layout_ptr child_layout = std::make_shared<text_layout>(output.get_font_manager(), output.get_scale_factor(), new_properties);
child_layout->init_orientation(feature); child_layout->init_orientation(feature,vars);
// process contained format tree into the child node // process contained format tree into the child node
if (child_) { if (child_) {
child_->apply(p, feature, *child_layout); child_->apply(p, feature, vars, *child_layout);
} else { } else {
MAPNIK_LOG_WARN(format) << "Useless layout node: Contains no text"; MAPNIK_LOG_WARN(format) << "Useless layout node: Contains no text";
} }

View file

@ -42,11 +42,11 @@ void list_node::to_xml(boost::property_tree::ptree & xml) const
} }
void list_node::apply(char_properties_ptr p, feature_impl const& feature, text_layout & output) const void list_node::apply(char_properties_ptr p, feature_impl const& feature, attributes const& vars, text_layout & output) const
{ {
for (node_ptr const& node : children_) for (node_ptr const& node : children_)
{ {
node->apply(p, feature, output); node->apply(p, feature, vars, output);
} }
} }

View file

@ -28,13 +28,9 @@
#include <mapnik/xml_node.hpp> #include <mapnik/xml_node.hpp>
#include <mapnik/text/layout.hpp> #include <mapnik/text/layout.hpp>
//boost
// boost // boost
#include <boost/property_tree/ptree.hpp> #include <boost/property_tree/ptree.hpp>
namespace mapnik namespace mapnik
{ {
namespace formatting namespace formatting
@ -54,9 +50,9 @@ node_ptr text_node::from_xml(xml_node const& xml)
return std::make_shared<text_node>(xml.get_value<expression_ptr>()); return std::make_shared<text_node>(xml.get_value<expression_ptr>());
} }
void text_node::apply(char_properties_ptr p, feature_impl const& feature, text_layout &output) const void text_node::apply(char_properties_ptr p, feature_impl const& feature, attributes const& vars, text_layout &output) const
{ {
mapnik::value_unicode_string text_str = boost::apply_visitor(evaluate<feature_impl,value_type>(feature), *text_).to_unicode(); mapnik::value_unicode_string text_str = boost::apply_visitor(evaluate<feature_impl,value_type,attributes>(feature,vars), *text_).to_unicode();
if (p->text_transform == UPPERCASE) if (p->text_transform == UPPERCASE)
{ {
text_str = text_str.toUpper(); text_str = text_str.toUpper();

View file

@ -235,12 +235,12 @@ void text_layout::shape_text(text_line & line)
shaper_type::shape_text(line, itemizer_, width_map_, font_manager_, scale_factor_); shaper_type::shape_text(line, itemizer_, width_map_, font_manager_, scale_factor_);
} }
void text_layout::init_orientation(feature_impl const& feature) void text_layout::init_orientation(feature_impl const& feature, attributes const& attr)
{ {
if (properties_->orientation) if (properties_->orientation)
{ {
// https://github.com/mapnik/mapnik/issues/1352 // https://github.com/mapnik/mapnik/issues/1352
mapnik::evaluate<feature_impl, value_type> evaluator(feature); mapnik::evaluate<feature_impl, value_type, attributes> evaluator(feature,attr);
orientation_.init( orientation_.init(
boost::apply_visitor( boost::apply_visitor(
evaluator, evaluator,

View file

@ -41,12 +41,14 @@ namespace mapnik
{ {
placement_finder::placement_finder(feature_impl const& feature, placement_finder::placement_finder(feature_impl const& feature,
attributes const& attr,
DetectorType &detector, DetectorType &detector,
box2d<double> const& extent, box2d<double> const& extent,
text_placement_info_ptr placement_info, text_placement_info_ptr placement_info,
face_manager_freetype & font_manager, face_manager_freetype & font_manager,
double scale_factor) double scale_factor)
: feature_(feature), : feature_(feature),
attr_(attr),
detector_(detector), detector_(detector),
extent_(extent), extent_(extent),
info_(placement_info), info_(placement_info),
@ -74,8 +76,8 @@ bool placement_finder::next_position()
} }
text_layout_ptr layout = std::make_shared<text_layout>(font_manager_, scale_factor_, info_->properties.layout_defaults); text_layout_ptr layout = std::make_shared<text_layout>(font_manager_, scale_factor_, info_->properties.layout_defaults);
layout->init_orientation(feature_); layout->init_orientation(feature_, attr_);
info_->properties.process(*layout, feature_); info_->properties.process(*layout, feature_, attr_);
layouts_.clear(); layouts_.clear();
layouts_.add(layout); layouts_.add(layout);
@ -266,11 +268,11 @@ bool placement_finder::single_line_placement(vertex_cache &pp, text_upright_e or
for (auto const& line : layout) for (auto const& line : layout)
{ {
//Only subtract half the line height here and half at the end because text is automatically // Only subtract half the line height here and half at the end because text is automatically
//centered on the line // centered on the line
offset -= sign * line.height()/2; offset -= sign * line.height()/2;
vertex_cache & off_pp = pp.get_offseted(offset, sign*layout.width()); vertex_cache & off_pp = pp.get_offseted(offset, sign*layout.width());
vertex_cache::scoped_state off_state(off_pp); //TODO: Remove this when a clean implementation in vertex_cache::get_offseted was done vertex_cache::scoped_state off_state(off_pp); // TODO: Remove this when a clean implementation in vertex_cache::get_offseted is done
if (!off_pp.move(sign * layout.jalign_offset(line.width()) - align_offset.x)) return false; if (!off_pp.move(sign * layout.jalign_offset(line.width()) - align_offset.x)) return false;
@ -291,7 +293,7 @@ bool placement_finder::single_line_placement(vertex_cache &pp, text_upright_e or
} }
current_cluster = glyph.char_index; current_cluster = glyph.char_index;
last_glyph_spacing = glyph.format->character_spacing * scale_factor_; last_glyph_spacing = glyph.format->character_spacing * scale_factor_;
//Only calculate new angle at the start of each cluster! // Only calculate new angle at the start of each cluster!
angle = normalize_angle(off_pp.angle(sign * layout.cluster_width(current_cluster))); angle = normalize_angle(off_pp.angle(sign * layout.cluster_width(current_cluster)));
rot.init(angle); rot.init(angle);
if ((info_->properties.max_char_angle_delta > 0) && (last_cluster_angle != 999) && if ((info_->properties.max_char_angle_delta > 0) && (last_cluster_angle != 999) &&
@ -306,7 +308,7 @@ bool placement_finder::single_line_placement(vertex_cache &pp, text_upright_e or
if (std::abs(angle) > M_PI/2) ++upside_down_glyph_count; if (std::abs(angle) > M_PI/2) ++upside_down_glyph_count;
pixel_position pos = off_pp.current_position() + cluster_offset; pixel_position pos = off_pp.current_position() + cluster_offset;
//Center the text on the line // Center the text on the line
double char_height = line.max_char_height(); double char_height = line.max_char_height();
pos.y = -pos.y - char_height/2.0*rot.cos; pos.y = -pos.y - char_height/2.0*rot.cos;
pos.x = pos.x + char_height/2.0*rot.sin; pos.x = pos.x + char_height/2.0*rot.sin;
@ -319,20 +321,20 @@ bool placement_finder::single_line_placement(vertex_cache &pp, text_upright_e or
bboxes.push_back(std::move(bbox)); bboxes.push_back(std::move(bbox));
glyphs->push_back(glyph, pos, rot); glyphs->push_back(glyph, pos, rot);
} }
//See comment above // See comment above
offset -= sign * line.height()/2; offset -= sign * line.height()/2;
} }
} }
if (upside_down_glyph_count > (layouts_.text().length() / 2)) if (upside_down_glyph_count > static_cast<unsigned>(layouts_.text().length() / 2))
{ {
if (orientation == UPRIGHT_AUTO) if (orientation == UPRIGHT_AUTO)
{ {
//Try again with oposite orientation // Try again with opposite orientation
begin.restore(); begin.restore();
return single_line_placement(pp, real_orientation == UPRIGHT_RIGHT ? UPRIGHT_LEFT : UPRIGHT_RIGHT); return single_line_placement(pp, real_orientation == UPRIGHT_RIGHT ? UPRIGHT_LEFT : UPRIGHT_RIGHT);
} }
//upright==left_only or right_only and more than 50% of characters upside down => no placement // upright==left_only or right_only and more than 50% of characters upside down => no placement
else if (orientation == UPRIGHT_LEFT_ONLY || orientation == UPRIGHT_RIGHT_ONLY) else if (orientation == UPRIGHT_LEFT_ONLY || orientation == UPRIGHT_RIGHT_ONLY)
{ {
return false; return false;

View file

@ -41,19 +41,23 @@
namespace mapnik { namespace mapnik {
base_symbolizer_helper::base_symbolizer_helper( base_symbolizer_helper::base_symbolizer_helper(
const symbolizer_base &sym, const feature_impl &feature, symbolizer_base const& sym,
const proj_transform &prj_trans, feature_impl const& feature,
attributes const& vars,
proj_transform const& prj_trans,
unsigned width, unsigned height, double scale_factor, unsigned width, unsigned height, double scale_factor,
const CoordTransform &t, const box2d<double> &query_extent) CoordTransform const& t,
box2d<double> const& query_extent)
: sym_(sym), : sym_(sym),
feature_(feature), feature_(feature),
vars_(vars),
prj_trans_(prj_trans), prj_trans_(prj_trans),
t_(t), t_(t),
dims_(0, 0, width, height), dims_(0, 0, width, height),
query_extent_(query_extent), query_extent_(query_extent),
scale_factor_(scale_factor), scale_factor_(scale_factor),
clipped_(mapnik::get<bool>(sym_, keys::clip, feature_, true /*TODO*/)), clipped_(get<bool>(sym_, keys::clip, feature_, vars, true)),
placement_(mapnik::get<text_placements_ptr>(sym_, keys::text_placements_)->get_placement_info(scale_factor)) placement_(get<text_placements_ptr>(sym_, keys::text_placements_)->get_placement_info(scale_factor))
{ {
initialize_geometries(); initialize_geometries();
if (!geometries_to_process_.size()) return; if (!geometries_to_process_.size()) return;
@ -74,8 +78,8 @@ struct largest_bbox_first
void base_symbolizer_helper::initialize_geometries() void base_symbolizer_helper::initialize_geometries()
{ {
// FIXME // FIXME
bool largest_box_only = false;//get<value_bool>(sym_, keys::largest_box_only); bool largest_box_only = get<value_bool>(sym_, keys::largest_box_only, feature_, vars_, false);
double minimum_path_length = 0; // get<value_double>(sym_, keys::minimum_path_length); double minimum_path_length = get<value_double>(sym_, keys::minimum_path_length, feature_, vars_, 0);
for ( auto const& geom : feature_.paths()) for ( auto const& geom : feature_.paths())
{ {
// don't bother with empty geometries // don't bother with empty geometries
@ -172,13 +176,15 @@ void base_symbolizer_helper::initialize_points()
template <typename FaceManagerT, typename DetectorT> template <typename FaceManagerT, typename DetectorT>
text_symbolizer_helper::text_symbolizer_helper( text_symbolizer_helper::text_symbolizer_helper(
const text_symbolizer &sym, const feature_impl &feature, text_symbolizer const& sym,
const proj_transform &prj_trans, feature_impl const& feature,
attributes const& vars,
proj_transform const& prj_trans,
unsigned width, unsigned height, double scale_factor, unsigned width, unsigned height, double scale_factor,
const CoordTransform &t, FaceManagerT &font_manager, CoordTransform const& t, FaceManagerT & font_manager,
DetectorT &detector, const box2d<double> &query_extent) DetectorT &detector, const box2d<double> &query_extent)
: base_symbolizer_helper(sym, feature, prj_trans, width, height, scale_factor, t, query_extent), : base_symbolizer_helper(sym, feature, vars, prj_trans, width, height, scale_factor, t, query_extent),
finder_(feature, detector, dims_, placement_, font_manager, scale_factor), finder_(feature, vars, detector, dims_, placement_, font_manager, scale_factor),
points_on_line_(false) points_on_line_(false)
{ {
if (geometries_to_process_.size()) finder_.next_position(); if (geometries_to_process_.size()) finder_.next_position();
@ -267,13 +273,15 @@ bool text_symbolizer_helper::next_point_placement()
template <typename FaceManagerT, typename DetectorT> template <typename FaceManagerT, typename DetectorT>
text_symbolizer_helper::text_symbolizer_helper( text_symbolizer_helper::text_symbolizer_helper(
const shield_symbolizer &sym, const feature_impl &feature, shield_symbolizer const& sym,
const proj_transform &prj_trans, feature_impl const& feature,
attributes const& vars,
proj_transform const& prj_trans,
unsigned width, unsigned height, double scale_factor, unsigned width, unsigned height, double scale_factor,
const CoordTransform &t, FaceManagerT &font_manager, CoordTransform const& t, FaceManagerT & font_manager,
DetectorT &detector, const box2d<double> &query_extent) DetectorT &detector, const box2d<double> &query_extent)
: base_symbolizer_helper(sym, feature, prj_trans, width, height, scale_factor, t, query_extent), : base_symbolizer_helper(sym, feature, vars, prj_trans, width, height, scale_factor, t, query_extent),
finder_(feature, detector, dims_, placement_, font_manager, scale_factor), finder_(feature, vars, detector, dims_, placement_, font_manager, scale_factor),
points_on_line_(true) points_on_line_(true)
{ {
if (geometries_to_process_.size()) if (geometries_to_process_.size())
@ -286,23 +294,17 @@ text_symbolizer_helper::text_symbolizer_helper(
void text_symbolizer_helper::init_marker() void text_symbolizer_helper::init_marker()
{ {
//shield_symbolizer const& sym = static_cast<shield_symbolizer const&>(sym_); std::string filename = mapnik::get<std::string>(sym_, keys::file, feature_, vars_);
std::string filename = mapnik::get<std::string>(sym_, keys::file, feature_); if (filename.empty()) return;
boost::optional<mapnik::marker_ptr> marker = marker_cache::instance().find(filename, true);
if (!marker) return;
//FIXME - need to test this //FIXME - need to test this
//std::string filename = path_processor_type::evaluate(filename_string, feature_); //std::string filename = path_processor_type::evaluate(filename_string, feature_);
agg::trans_affine trans; agg::trans_affine trans;
auto image_transform = get_optional<transform_type>(sym_, keys::image_transform); auto image_transform = get_optional<transform_type>(sym_, keys::image_transform);
if (image_transform) evaluate_transform(trans, feature_, *image_transform); if (image_transform) evaluate_transform(trans, feature_, vars_, *image_transform);
boost::optional<marker_ptr> opt_marker; //TODO: Why boost::optional? double width = (*marker)->width();
if (!filename.empty()) double height = (*marker)->height();
{
opt_marker = marker_cache::instance().find(filename, true);
}
marker_ptr m;
if (opt_marker) m = *opt_marker;
if (!m) return;
double width = m->width();
double height = m->height();
double px0 = - 0.5 * width; double px0 = - 0.5 * width;
double py0 = - 0.5 * height; double py0 = - 0.5 * height;
double px1 = 0.5 * width; double px1 = 0.5 * width;
@ -318,35 +320,39 @@ void text_symbolizer_helper::init_marker()
box2d<double> bbox(px0, py0, px1, py1); box2d<double> bbox(px0, py0, px1, py1);
bbox.expand_to_include(px2, py2); bbox.expand_to_include(px2, py2);
bbox.expand_to_include(px3, py3); bbox.expand_to_include(px3, py3);
bool unlock_image = mapnik::get<value_bool>(sym_, keys::unlock_image, false); bool unlock_image = mapnik::get<value_bool>(sym_, keys::unlock_image, feature_, vars_, false);
double shield_dx = mapnik::get<value_double>(sym_, keys::shield_dx, 0.0); double shield_dx = mapnik::get<value_double>(sym_, keys::shield_dx, feature_, vars_, 0.0);
double shield_dy = mapnik::get<value_double>(sym_, keys::shield_dy, 0.0); double shield_dy = mapnik::get<value_double>(sym_, keys::shield_dy, feature_, vars_, 0.0);
pixel_position marker_displacement; pixel_position marker_displacement;
marker_displacement.set(shield_dx,shield_dy); marker_displacement.set(shield_dx,shield_dy);
finder_.set_marker(std::make_shared<marker_info>(m, trans), bbox, unlock_image, marker_displacement); finder_.set_marker(std::make_shared<marker_info>(*marker, trans), bbox, unlock_image, marker_displacement);
} }
/*****************************************************************************/ /*****************************************************************************/
template text_symbolizer_helper::text_symbolizer_helper(const text_symbolizer &sym, template text_symbolizer_helper::text_symbolizer_helper(
const feature_impl &feature, text_symbolizer const& sym,
const proj_transform &prj_trans, feature_impl const& feature,
attributes const& vars,
proj_transform const& prj_trans,
unsigned width, unsigned width,
unsigned height, unsigned height,
double scale_factor, double scale_factor,
const CoordTransform &t, CoordTransform const& t,
face_manager<freetype_engine> &font_manager, face_manager<freetype_engine> &font_manager,
label_collision_detector4 &detector, label_collision_detector4 &detector,
const box2d<double> &query_extent); box2d<double> const& query_extent);
template text_symbolizer_helper::text_symbolizer_helper(const shield_symbolizer &sym, template text_symbolizer_helper::text_symbolizer_helper(
const feature_impl &feature, shield_symbolizer const& sym,
const proj_transform &prj_trans, feature_impl const& feature,
attributes const& vars,
proj_transform const& prj_trans,
unsigned width, unsigned width,
unsigned height, unsigned height,
double scale_factor, double scale_factor,
const CoordTransform &t, CoordTransform const& t,
face_manager<freetype_engine> &font_manager, face_manager<freetype_engine> &font_manager,
label_collision_detector4 &detector, label_collision_detector4 &detector,
const box2d<double> &query_extent); box2d<double> const& query_extent);
} //namespace } //namespace

View file

@ -118,11 +118,11 @@ text_symbolizer_properties::text_symbolizer_properties() :
} }
void text_symbolizer_properties::process(text_layout &output, feature_impl const& feature) const void text_symbolizer_properties::process(text_layout &output, feature_impl const& feature, attributes const& vars) const
{ {
output.clear(); output.clear();
if (tree_) { if (tree_) {
tree_->apply(format, feature, output); tree_->apply(format, feature, vars, output);
} else { } else {
MAPNIK_LOG_WARN(text_properties) << "text_symbolizer_properties can't produce text: No formatting tree!"; MAPNIK_LOG_WARN(text_properties) << "text_symbolizer_properties can't produce text: No formatting tree!";
} }

View file

@ -62,7 +62,7 @@ boost::optional<std::string> linestring_bbox_clipping(mapnik::box2d<double> bbox
mapnik::feature_impl f(ctx,0); mapnik::feature_impl f(ctx,0);
vertex_converter<box2d<double>, output_geometry_backend, line_symbolizer, vertex_converter<box2d<double>, output_geometry_backend, line_symbolizer,
CoordTransform, proj_transform, agg::trans_affine, conv_types, feature_impl> CoordTransform, proj_transform, agg::trans_affine, conv_types, feature_impl>
converter(bbox, backend, sym, t, prj_trans, tr, f, 1.0); converter(bbox, backend, sym, t, prj_trans, tr, f, attributes(), 1.0);
converter.set<clip_line_tag>(); converter.set<clip_line_tag>();
@ -104,7 +104,7 @@ boost::optional<std::string> polygon_bbox_clipping(mapnik::box2d<double> bbox,
mapnik::feature_impl f(ctx,0); mapnik::feature_impl f(ctx,0);
vertex_converter<box2d<double>, output_geometry_backend, polygon_symbolizer, vertex_converter<box2d<double>, output_geometry_backend, polygon_symbolizer,
CoordTransform, proj_transform, agg::trans_affine, conv_types, feature_impl> CoordTransform, proj_transform, agg::trans_affine, conv_types, feature_impl>
converter(bbox, backend, sym, t, prj_trans, tr, f, 1.0); converter(bbox, backend, sym, t, prj_trans, tr, f, attributes(), 1.0);
converter.set<clip_poly_tag>(); converter.set<clip_poly_tag>();

View file

@ -44,7 +44,7 @@ void prepare_map(Map & m)
put(poly_sym, keys::fill, color(250, 190, 183)); put(poly_sym, keys::fill, color(250, 190, 183));
r.append(std::move(poly_sym)); r.append(std::move(poly_sym));
} }
provpoly_style.add_rule(r); provpoly_style.add_rule(std::move(r));
} }
{ {
rule r; rule r;
@ -54,7 +54,7 @@ void prepare_map(Map & m)
put(poly_sym, keys::fill, color(217, 235, 203)); put(poly_sym, keys::fill, color(217, 235, 203));
r.append(std::move(poly_sym)); r.append(std::move(poly_sym));
} }
provpoly_style.add_rule(r); provpoly_style.add_rule(std::move(r));
} }
m.insert_style("provinces",provpoly_style); m.insert_style("provinces",provpoly_style);
@ -73,7 +73,7 @@ void prepare_map(Map & m)
put(line_sym,keys::stroke_dasharray,dash); put(line_sym,keys::stroke_dasharray,dash);
r.append(std::move(line_sym)); r.append(std::move(line_sym));
} }
provlines_style.add_rule(r); provlines_style.add_rule(std::move(r));
} }
m.insert_style("provlines",provlines_style); m.insert_style("provlines",provlines_style);
@ -87,7 +87,7 @@ void prepare_map(Map & m)
put(poly_sym, keys::fill, color(153, 204, 255)); put(poly_sym, keys::fill, color(153, 204, 255));
r.append(std::move(poly_sym)); r.append(std::move(poly_sym));
} }
qcdrain_style.add_rule(r); qcdrain_style.add_rule(std::move(r));
} }
m.insert_style("drainage",qcdrain_style); m.insert_style("drainage",qcdrain_style);
@ -104,7 +104,7 @@ void prepare_map(Map & m)
put(line_sym,keys::stroke_linejoin,ROUND_JOIN); put(line_sym,keys::stroke_linejoin,ROUND_JOIN);
r.append(std::move(line_sym)); r.append(std::move(line_sym));
} }
roads34_style.add_rule(r); roads34_style.add_rule(std::move(r));
} }
m.insert_style("smallroads",roads34_style); m.insert_style("smallroads",roads34_style);
@ -121,7 +121,7 @@ void prepare_map(Map & m)
put(line_sym,keys::stroke_linejoin,ROUND_JOIN); put(line_sym,keys::stroke_linejoin,ROUND_JOIN);
r.append(std::move(line_sym)); r.append(std::move(line_sym));
} }
roads2_style_1.add_rule(r); roads2_style_1.add_rule(std::move(r));
} }
m.insert_style("road-border", roads2_style_1); m.insert_style("road-border", roads2_style_1);
@ -137,7 +137,7 @@ void prepare_map(Map & m)
put(line_sym,keys::stroke_linejoin,ROUND_JOIN); put(line_sym,keys::stroke_linejoin,ROUND_JOIN);
r.append(std::move(line_sym)); r.append(std::move(line_sym));
} }
roads2_style_2.add_rule(r); roads2_style_2.add_rule(std::move(r));
} }
m.insert_style("road-fill", roads2_style_2); m.insert_style("road-fill", roads2_style_2);
@ -154,7 +154,7 @@ void prepare_map(Map & m)
put(line_sym,keys::stroke_linejoin,ROUND_JOIN); put(line_sym,keys::stroke_linejoin,ROUND_JOIN);
r.append(std::move(line_sym)); r.append(std::move(line_sym));
} }
roads1_style_1.add_rule(r); roads1_style_1.add_rule(std::move(r));
} }
m.insert_style("highway-border", roads1_style_1); m.insert_style("highway-border", roads1_style_1);
@ -170,7 +170,7 @@ void prepare_map(Map & m)
put(line_sym,keys::stroke_linejoin,ROUND_JOIN); put(line_sym,keys::stroke_linejoin,ROUND_JOIN);
r.append(std::move(line_sym)); r.append(std::move(line_sym));
} }
roads1_style_2.add_rule(r); roads1_style_2.add_rule(std::move(r));
} }
m.insert_style("highway-fill", roads1_style_2); m.insert_style("highway-fill", roads1_style_2);
@ -190,7 +190,7 @@ void prepare_map(Map & m)
put<text_placements_ptr>(text_sym, keys::text_placements_, placement_finder); put<text_placements_ptr>(text_sym, keys::text_placements_, placement_finder);
r.append(std::move(text_sym)); r.append(std::move(text_sym));
} }
popplaces_style.add_rule(r); popplaces_style.add_rule(std::move(r));
} }
m.insert_style("popplaces",popplaces_style ); m.insert_style("popplaces",popplaces_style );
@ -202,7 +202,6 @@ void prepare_map(Map & m)
p["type"]="shape"; p["type"]="shape";
p["file"]="demo/data/boundaries"; p["file"]="demo/data/boundaries";
p["encoding"]="latin1"; p["encoding"]="latin1";
layer lyr("Provinces"); layer lyr("Provinces");
lyr.set_datasource(datasource_cache::instance().create(p)); lyr.set_datasource(datasource_cache::instance().create(p));
lyr.set_srs(srs_lcc); lyr.set_srs(srs_lcc);

View file

@ -0,0 +1,18 @@
{
"type": "FeatureCollection",
"properties": {
"fc_name": "fc_value"
},
"features": [
{
"type": "Feature",
"properties": {
"feat_name": "feat_value"
},
"geometry": {
"type": "Point",
"coordinates": [ -122, 48 ]
}
}
]
}

View file

@ -66,6 +66,14 @@ if 'geojson' in mapnik.DatasourceCache.plugin_names():
# query.add_property_name('bogus') # query.add_property_name('bogus')
# fs = ds.features(query) # fs = ds.features(query)
def test_parsing_feature_collection_with_top_level_properties():
ds = mapnik.Datasource(type='geojson',file='../data/json/feature_collection_level_properties.json')
f = ds.all_features()[0]
desc = ds.describe()
eq_(desc['geometry_type'],mapnik.DataGeometryType.Point)
eq_(f['feat_name'], u'feat_value')
if __name__ == "__main__": if __name__ == "__main__":
setup() setup()
run_all(eval(x) for x in dir() if x.startswith("test_")) run_all(eval(x) for x in dir() if x.startswith("test_"))

View file

@ -1011,6 +1011,15 @@ if 'postgis' in mapnik.DatasourceCache.plugin_names() \
eq_(geoms[0].to_wkt(),'Polygon((0 0,1 1,2 2,0 0))') eq_(geoms[0].to_wkt(),'Polygon((0 0,1 1,2 2,0 0))')
eq_(geoms[1].to_wkt(),'Polygon((0 0,1 1,2 2,0 0))') eq_(geoms[1].to_wkt(),'Polygon((0 0,1 1,2 2,0 0))')
def test_variable_in_subquery1():
ds = mapnik.PostGIS(dbname=MAPNIK_TEST_DBNAME,table='''
(select * from test where @zoom = 30 ) as tmp''',
geometry_field='geom',
autodetect_key_field=True)
fs = ds.featureset(variables={'zoom':30})
for id in range(1,5):
eq_(fs.next().id(),id)
atexit.register(postgis_takedown) atexit.register(postgis_takedown)