diff --git a/.travis.yml b/.travis.yml
index 2dc9e93f2..ba6ace47a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -15,11 +15,11 @@ before_install:
# grab more recent gdal/proj
- sudo add-apt-repository -y ppa:ubuntugis/ubuntugis-unstable
# 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
# upgrade compilers
- 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
- tar xf harfbuzz-0.9.24.tar.bz2
- cd harfbuzz-0.9.24
diff --git a/benchmark/data/roads.xml b/benchmark/data/roads.xml
index eddc42d24..f6d4a2155 100644
--- a/benchmark/data/roads.xml
+++ b/benchmark/data/roads.xml
@@ -52,7 +52,7 @@
+#include
void render(mapnik::geometry_type & geom,
mapnik::box2d const& extent,
diff --git a/bindings/python/mapnik/__init__.py b/bindings/python/mapnik/__init__.py
index 934bf5a64..f98f1b60c 100644
--- a/bindings/python/mapnik/__init__.py
+++ b/bindings/python/mapnik/__init__.py
@@ -267,15 +267,17 @@ class _Path(Path,_injector):
class _Datasource(Datasource,_injector):
- def all_features(self,fields=None):
+ def all_features(self,fields=None,variables={}):
query = Query(self.envelope())
+ query.set_variables(variables);
attributes = fields or self.fields()
for fld in attributes:
query.add_property_name(fld)
return self.features(query).features
- def featureset(self,fields=None):
+ def featureset(self,fields=None,variables={}):
query = Query(self.envelope())
+ query.set_variables(variables);
attributes = fields or self.fields()
for fld in attributes:
query.add_property_name(fld)
diff --git a/bindings/python/mapnik_expression.cpp b/bindings/python/mapnik_expression.cpp
index d27be9bb5..fe64e6cd6 100644
--- a/bindings/python/mapnik_expression.cpp
+++ b/bindings/python/mapnik_expression.cpp
@@ -21,6 +21,7 @@
*****************************************************************************/
#include "boost_std_shared_shim.hpp"
+#include "python_to_value.hpp"
// boost
#include
@@ -53,15 +54,15 @@ std::string expression_to_string_(mapnik::expr_node const& 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`
- return boost::apply_visitor(mapnik::evaluate(f),expr);
+ return boost::apply_visitor(mapnik::evaluate(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(f),expr).to_bool();
+ return boost::apply_visitor(mapnik::evaluate(f,mapnik::dict2attr(d)),expr).to_bool();
}
// path expression
@@ -86,8 +87,8 @@ void export_expression()
class_("Expression",
"TODO"
"",no_init)
- .def("evaluate", &expression_evaluate_)
- .def("to_bool", &expression_evaluate_to_bool_)
+ .def("evaluate", &expression_evaluate_,(arg("feature"),arg("variables")=boost::python::dict()))
+ .def("to_bool", &expression_evaluate_to_bool_,(arg("feature"),arg("variables")=boost::python::dict()))
.def("__str__",&expression_to_string_);
;
diff --git a/bindings/python/mapnik_python.cpp b/bindings/python/mapnik_python.cpp
index d89cbf33f..f6d4f1645 100644
--- a/bindings/python/mapnik_python.cpp
+++ b/bindings/python/mapnik_python.cpp
@@ -21,6 +21,7 @@
*****************************************************************************/
#include "boost_std_shared_shim.hpp"
+#include "python_to_value.hpp"
#include // for keywords, arg, etc
#include
#include // for def
@@ -182,7 +183,18 @@ void render(mapnik::Map const& map,
python_unblock_auto_block b;
mapnik::agg_renderer ren(map,image,scale_factor,offset_x, offset_y);
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 ren(map,req,vars,image,1,0,0);
+ ren.apply();
}
void render_with_detector(
@@ -259,7 +271,6 @@ void render6(mapnik::Map const& map, PycairoContext* py_context)
mapnik::cairo_renderer ren(map,context);
ren.apply();
}
-
void render_with_detector2(
mapnik::Map const& map,
PycairoContext* py_context,
@@ -647,6 +658,7 @@ BOOST_PYTHON_MODULE(_mapnik)
"\n"
);
+ def("render_with_vars",&render_with_vars);
def("render", &render, render_overloads(
"\n"
diff --git a/bindings/python/mapnik_query.cpp b/bindings/python/mapnik_query.cpp
index 503b1e570..1384adc20 100644
--- a/bindings/python/mapnik_query.cpp
+++ b/bindings/python/mapnik_query.cpp
@@ -21,6 +21,7 @@
*****************************************************************************/
#include "boost_std_shared_shim.hpp"
+#include "python_to_value.hpp"
// boost
#include
@@ -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()
{
using namespace boost::python;
@@ -85,5 +95,6 @@ void export_query()
return_value_policy()) )
.add_property("property_names", make_function(&query::property_names,
return_value_policy()) )
- .def("add_property_name", &query::add_property_name);
+ .def("add_property_name", &query::add_property_name)
+ .def("set_variables",&set_variables);
}
diff --git a/bindings/python/mapnik_text_placement.cpp b/bindings/python/mapnik_text_placement.cpp
index 87e0360f9..1aebf931a 100644
--- a/bindings/python/mapnik_text_placement.cpp
+++ b/bindings/python/mapnik_text_placement.cpp
@@ -125,10 +125,10 @@ struct NodeWrap: formatting::node, wrapper
}
- 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;
- 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
@@ -163,85 +163,85 @@ struct TextNodeWrap: formatting::text_node, wrapper
}
- 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"))
{
python_block_auto_unblock b;
- o(ptr(&p), ptr(&feature), ptr(&output));
+ o(ptr(&p), ptr(&feature), ptr(&vars), ptr(&output));
}
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
{
- 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"))
{
python_block_auto_unblock b;
- o(ptr(&p), ptr(&feature), ptr(&output));
+ o(ptr(&p), ptr(&feature), ptr(&vars), ptr(&output));
}
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
{
- 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"))
{
python_block_auto_unblock b;
- o(ptr(&p), ptr(&feature), ptr(&output));
+ o(ptr(&p), ptr(&feature), ptr(&vars), ptr(&output));
}
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
{
- 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"))
{
python_block_auto_unblock b;
- o(ptr(&p), ptr(&feature), ptr(&output));
+ o(ptr(&p), ptr(&feature), ptr(&vars), ptr(&output));
}
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
/* TODO: Add constructor taking variable number of arguments.
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"))
{
python_block_auto_unblock b;
- o(ptr(&p), ptr(&feature), ptr(&output));
+ o(ptr(&p), ptr(&feature), ptr(&vars), ptr(&output));
}
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(){
diff --git a/bindings/python/python_to_value.hpp b/bindings/python/python_to_value.hpp
new file mode 100644
index 000000000..fd2eb4da2
--- /dev/null
+++ b/bindings/python/python_to_value.hpp
@@ -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
+
+// mapnik
+#include
+#include
+
+
+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(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 ex0(obj);
+ if (ex0.check())
+ {
+ vars[key] = tr_.transcode(ex0().c_str());
+ continue;
+ }
+ extract ex2(obj);
+ if (ex2.check())
+ {
+ vars[key] = ex2();
+ continue;
+ }
+ extract ex3(obj);
+ if (ex3.check())
+ {
+ vars[key] = ex3();
+ continue;
+ }
+ extract ex1(obj);
+ if (ex1.check())
+ {
+ vars[key] = ex1();
+ continue;
+ }
+ }
+ return vars;
+ }
+}
+
+#endif // MAPNIK_PYTHON_BINDING_PYTHON_TO_VALUE
diff --git a/include/mapnik/agg_helpers.hpp b/include/mapnik/agg_helpers.hpp
index 457ebd2e8..188bf404d 100644
--- a/include/mapnik/agg_helpers.hpp
+++ b/include/mapnik/agg_helpers.hpp
@@ -61,9 +61,9 @@ void set_gamma_method(T & ras_ptr, double gamma, gamma_method_enum method)
}
template
-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(sym, keys::stroke_linejoin, feature, MITER_JOIN);
+ line_join_enum join = get(sym, keys::stroke_linejoin, feature, vars, MITER_JOIN);
switch (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);
}
- line_cap_enum cap = get(sym, keys::stroke_linecap, feature, BUTT_CAP);
+ line_cap_enum cap = get(sym, keys::stroke_linecap, feature, vars, BUTT_CAP);
switch (cap)
{
@@ -96,9 +96,9 @@ void set_join_caps(Symbolizer const& sym, PathType & stroke, Feature const& feat
template
-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(sym, keys::stroke_linejoin, feature, MITER_JOIN);
+ line_join_enum join = get(sym, keys::stroke_linejoin, feature, vars, MITER_JOIN);
switch (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);
}
- line_cap_enum cap = get(sym, keys::stroke_linecap, feature, BUTT_CAP);
+ line_cap_enum cap = get(sym, keys::stroke_linecap, feature, vars, BUTT_CAP);
switch (cap)
{
diff --git a/include/mapnik/agg_renderer.hpp b/include/mapnik/agg_renderer.hpp
index 5e6e43dd9..b16053dd4 100644
--- a/include/mapnik/agg_renderer.hpp
+++ b/include/mapnik/agg_renderer.hpp
@@ -73,7 +73,7 @@ public:
agg_renderer(Map const &m, buffer_type & pixmap, std::shared_ptr detector,
double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0);
// pass in mapnik::request object to provide the mutable things per render
- agg_renderer(Map const& m, request const& req, 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();
void start_map_processing(Map const& map);
void end_map_processing(Map const& map);
@@ -142,6 +142,11 @@ public:
return common_.scale_factor_;
}
+ inline attributes const& variables() const
+ {
+ return common_.vars_;
+ }
+
inline box2d clipping_extent() const
{
if (common_.t_.offset() > 0)
diff --git a/include/mapnik/attribute.hpp b/include/mapnik/attribute.hpp
index b403bc7db..e280f2502 100644
--- a/include/mapnik/attribute.hpp
+++ b/include/mapnik/attribute.hpp
@@ -26,9 +26,11 @@
// mapnik
#include
#include
+#include
// stl
#include
+#include
namespace mapnik {
@@ -78,6 +80,8 @@ struct global_attribute
}
};
+typedef std::unordered_map attributes;
+
}
#endif // MAPNIK_ATTRIBUTE_HPP
diff --git a/include/mapnik/cairo_renderer.hpp b/include/mapnik/cairo_renderer.hpp
index 5b101de48..645fbff49 100644
--- a/include/mapnik/cairo_renderer.hpp
+++ b/include/mapnik/cairo_renderer.hpp
@@ -58,17 +58,20 @@ class MAPNIK_DECL cairo_renderer_base : private mapnik::noncopyable
protected:
cairo_renderer_base(Map const& m,
cairo_ptr const& cairo,
+ attributes const& vars,
double scale_factor=1.0,
unsigned offset_x=0,
unsigned offset_y=0);
cairo_renderer_base(Map const& m,
request const& req,
cairo_ptr const& cairo,
+ attributes const& vars,
double scale_factor=1.0,
unsigned offset_x=0,
unsigned offset_y=0);
cairo_renderer_base(Map const& m,
cairo_ptr const& cairo,
+ attributes const& vars,
std::shared_ptr detector,
double scale_factor=1.0,
unsigned offset_x=0,
@@ -138,6 +141,11 @@ public:
return common_.scale_factor_;
}
+ inline attributes const& variables() const
+ {
+ return common_.vars_;
+ }
+
void render_marker(pixel_position const& pos,
marker const& marker,
agg::trans_affine const& mtx,
@@ -165,6 +173,7 @@ public:
unsigned offset_y=0);
cairo_renderer(Map const& m,
request const& req,
+ attributes const& vars,
T const& obj,
double scale_factor=1.0,
unsigned offset_x=0,
diff --git a/include/mapnik/expression_evaluator.hpp b/include/mapnik/expression_evaluator.hpp
index 7da728301..b306b1f40 100644
--- a/include/mapnik/expression_evaluator.hpp
+++ b/include/mapnik/expression_evaluator.hpp
@@ -39,14 +39,16 @@
namespace mapnik
{
-template
+template
struct evaluate : boost::static_visitor
{
typedef T0 feature_type;
typedef T1 value_type;
+ typedef T2 variable_type;
- explicit evaluate(feature_type const& f)
- : feature_(f) {}
+ explicit evaluate(feature_type const& f, variable_type const& v)
+ : feature_(f),
+ vars_(v) {}
value_integer operator() (value_integer val) const
{
@@ -80,7 +82,12 @@ struct evaluate : boost::static_visitor
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
@@ -144,6 +151,7 @@ struct evaluate : boost::static_visitor
}
feature_type const& feature_;
+ variable_type const& vars_;
};
}
diff --git a/include/mapnik/feature_style_processor_impl.hpp b/include/mapnik/feature_style_processor_impl.hpp
index 33cb5354e..8ebdcf63f 100644
--- a/include/mapnik/feature_style_processor_impl.hpp
+++ b/include/mapnik/feature_style_processor_impl.hpp
@@ -471,6 +471,7 @@ void feature_style_processor::prepare_layer(layer_rendering_material
height/qh);
query q(layer_ext,res,scale_denom,extent);
+ q.set_variables(p.variables());
if (p.attribute_collection_policy() == COLLECT_ALL)
{
@@ -643,6 +644,7 @@ void feature_style_processor::render_style(
p.end_style_processing(*style);
return;
}
+ mapnik::attributes vars = p.variables();
feature_ptr feature;
bool was_painted = false;
while ((feature = features->next()))
@@ -652,7 +654,7 @@ void feature_style_processor::render_style(
for (rule const* r : rc.get_if_rules() )
{
expression_ptr const& expr = r->get_filter();
- value_type result = boost::apply_visitor(evaluate(*feature),*expr);
+ value_type result = boost::apply_visitor(evaluate(*feature,vars),*expr);
if (result.to_bool())
{
was_painted = true;
diff --git a/include/mapnik/grid/grid_marker_helpers.hpp b/include/mapnik/grid/grid_marker_helpers.hpp
index 1f75e7192..2022e2df3 100644
--- a/include/mapnik/grid/grid_marker_helpers.hpp
+++ b/include/mapnik/grid/grid_marker_helpers.hpp
@@ -55,6 +55,7 @@ struct raster_markers_rasterizer_dispatch_grid
Detector & detector,
double scale_factor,
mapnik::feature_impl & feature,
+ attributes const& vars,
PixMapType & pixmap)
: buf_(render_buffer),
pixf_(buf_),
@@ -66,29 +67,19 @@ struct raster_markers_rasterizer_dispatch_grid
detector_(detector),
scale_factor_(scale_factor),
feature_(feature),
+ vars_(vars),
pixmap_(pixmap),
placed_(false)
- {
- // TODO - support basic binary operators
- //pixf_.comp_op(static_cast(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
void add_path(T & path)
{
- marker_placement_enum placement_method = get(sym_, keys::markers_placement_type, MARKER_POINT_PLACEMENT);
- bool ignore_placement = get(sym_, keys::ignore_placement, false);
- bool allow_overlap = get(sym_, keys::allow_overlap, false);
- double spacing = get(sym_, keys::spacing, 100.0);
- double max_error = get(sym_, keys::max_error, 0.2);
+ agg::scanline_bin sl_;
+ marker_placement_enum placement_method = get(sym_, keys::markers_placement_type, feature_, vars_, MARKER_POINT_PLACEMENT);
+ bool ignore_placement = get(sym_, keys::ignore_placement, feature_, vars_, false);
+ bool allow_overlap = get(sym_, keys::allow_overlap, feature_, vars_, false);
box2d bbox_(0,0, src_.width(),src_.height());
if (placement_method != MARKER_LINE_PLACEMENT ||
@@ -99,17 +90,23 @@ struct raster_markers_rasterizer_dispatch_grid
if (path.type() == geometry_type::types::LineString)
{
if (!label::middle_point(path, x, y))
+ {
return;
+ }
}
else if (placement_method == MARKER_INTERIOR_PLACEMENT)
{
if (!label::interior_position(path, x, y))
+ {
return;
+ }
}
else
{
if (!label::centroid(path, x, y))
+ {
return;
+ }
}
agg::trans_affine matrix = marker_trans_;
matrix.translate(x,y);
@@ -131,6 +128,8 @@ struct raster_markers_rasterizer_dispatch_grid
}
else
{
+ double spacing = get(sym_, keys::spacing, feature_, vars_, 100.0);
+ double max_error = get(sym_, keys::max_error, feature_, vars_, 0.2);
markers_placement placement(path, bbox_, marker_trans_, detector_,
spacing * scale_factor_,
max_error,
@@ -153,6 +152,7 @@ struct raster_markers_rasterizer_dispatch_grid
void render_raster_marker(agg::trans_affine const& marker_tr)
{
+ agg::scanline_bin sl_;
double width = src_.width();
double height = src_.height();
double p[8];
@@ -174,7 +174,6 @@ struct raster_markers_rasterizer_dispatch_grid
}
private:
- agg::scanline_bin sl_;
BufferType & buf_;
PixFmt pixf_;
RendererBase renb_;
@@ -185,6 +184,7 @@ private:
Detector & detector_;
double scale_factor_;
mapnik::feature_impl & feature_;
+ attributes const& vars_;
PixMapType & pixmap_;
bool placed_;
};
@@ -208,6 +208,7 @@ struct vector_markers_rasterizer_dispatch_grid
Detector & detector,
double scale_factor,
mapnik::feature_impl & feature,
+ attributes const& vars,
PixMapType & pixmap)
: buf_(render_buffer),
pixf_(buf_),
@@ -220,30 +221,20 @@ struct vector_markers_rasterizer_dispatch_grid
detector_(detector),
scale_factor_(scale_factor),
feature_(feature),
+ vars_(vars),
pixmap_(pixmap),
placed_(false)
- {
- // TODO
- //pixf_.comp_op(static_cast(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
void add_path(T & path)
{
- marker_placement_enum placement_method = get(sym_, keys::markers_placement_type, MARKER_POINT_PLACEMENT);
- bool ignore_placement = get(sym_, keys::ignore_placement, false);
- double spacing = get(sym_, keys::spacing, 100.0);
- double max_error = get(sym_, keys::max_error, 0.2);
- double opacity = get(sym_,keys::opacity, 1.0);
- bool allow_overlap = get(sym_, keys::allow_overlap, false);
+ agg::scanline_bin sl_;
+ marker_placement_enum placement_method = get(sym_, keys::markers_placement_type, feature_, vars_, MARKER_POINT_PLACEMENT);
+ bool ignore_placement = get(sym_, keys::ignore_placement, feature_, vars_, false);
+ double opacity = get(sym_,keys::opacity, feature_, vars_, 1.0);
+ bool allow_overlap = get(sym_, keys::allow_overlap, feature_, vars_, false);
if (placement_method != MARKER_LINE_PLACEMENT ||
path.type() == geometry_type::types::Point)
@@ -253,17 +244,23 @@ struct vector_markers_rasterizer_dispatch_grid
if (path.type() == geometry_type::types::LineString)
{
if (!label::middle_point(path, x, y))
+ {
return;
+ }
}
else if (placement_method == MARKER_INTERIOR_PLACEMENT)
{
if (!label::interior_position(path, x, y))
+ {
return;
+ }
}
else
{
if (!label::centroid(path, x, y))
+ {
return;
+ }
}
agg::trans_affine matrix = marker_trans_;
matrix.translate(x,y);
@@ -285,6 +282,8 @@ struct vector_markers_rasterizer_dispatch_grid
}
else
{
+ double spacing = get(sym_, keys::spacing, feature_, vars_, 100.0);
+ double max_error = get(sym_, keys::max_error, feature_, vars_, 0.2);
markers_placement placement(path, bbox_, marker_trans_, detector_,
spacing * scale_factor_,
max_error,
@@ -305,7 +304,6 @@ struct vector_markers_rasterizer_dispatch_grid
}
}
private:
- agg::scanline_bin sl_;
BufferType & buf_;
pixfmt_type pixf_;
renderer_base renb_;
@@ -317,10 +315,10 @@ private:
Detector & detector_;
double scale_factor_;
mapnik::feature_impl & feature_;
+ attributes const& vars_;
PixMapType & pixmap_;
bool placed_;
};
-
}
#endif
diff --git a/include/mapnik/grid/grid_renderer.hpp b/include/mapnik/grid/grid_renderer.hpp
index fe9e3e0ee..debc69dbc 100644
--- a/include/mapnik/grid/grid_renderer.hpp
+++ b/include/mapnik/grid/grid_renderer.hpp
@@ -68,7 +68,7 @@ public:
typedef T buffer_type;
typedef grid_renderer 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, 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();
void start_map_processing(Map const& map);
void end_map_processing(Map const& map);
@@ -131,6 +131,11 @@ public:
return common_.scale_factor_;
}
+ inline attributes const& variables() const
+ {
+ return common_.vars_;
+ }
+
private:
buffer_type & pixmap_;
const std::unique_ptr ras_ptr;
diff --git a/include/mapnik/group/group_symbolizer_helper.hpp b/include/mapnik/group/group_symbolizer_helper.hpp
index fb9619cfc..62d161236 100644
--- a/include/mapnik/group/group_symbolizer_helper.hpp
+++ b/include/mapnik/group/group_symbolizer_helper.hpp
@@ -55,6 +55,7 @@ public:
group_symbolizer_helper(group_symbolizer const& sym,
feature_impl const& feature,
+ attributes const& vars,
proj_transform const& prj_trans,
unsigned width,
unsigned height,
diff --git a/include/mapnik/marker_helpers.hpp b/include/mapnik/marker_helpers.hpp
index 8241778d9..3c7c9fa9f 100644
--- a/include/mapnik/marker_helpers.hpp
+++ b/include/mapnik/marker_helpers.hpp
@@ -34,6 +34,7 @@
#include // for svg_storage_type
#include
#include
+#include
// agg
#include "agg_ellipse.h"
@@ -74,6 +75,8 @@ struct vector_markers_rasterizer_dispatch
agg::trans_affine const& marker_trans,
markers_symbolizer const& sym,
Detector & detector,
+ feature_impl & feature,
+ attributes const& vars,
double scale_factor,
bool snap_to_pixels)
: buf_(render_buffer),
@@ -85,26 +88,22 @@ struct vector_markers_rasterizer_dispatch
marker_trans_(marker_trans),
sym_(sym),
detector_(detector),
+ feature_(feature),
+ vars_(vars),
scale_factor_(scale_factor),
snap_to_pixels_(snap_to_pixels)
{
- pixf_.comp_op(get(sym_, keys::comp_op, 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_)
- {
+ pixf_.comp_op(get(sym_, keys::comp_op, feature_, vars_, agg::comp_op_src_over));
}
template
void add_path(T & path)
{
- marker_placement_enum placement_method = get(sym_, keys::markers_placement_type, MARKER_POINT_PLACEMENT);
- bool ignore_placement = get(sym_, keys::ignore_placement, false);
- bool allow_overlap = get(sym_, keys::allow_overlap, false);
- double opacity = get(sym_,keys::opacity, 1.0);
+ agg::scanline_u8 sl_;
+ marker_placement_enum placement_method = get(sym_, keys::markers_placement_type, feature_, vars_, MARKER_POINT_PLACEMENT);
+ bool ignore_placement = get(sym_, keys::ignore_placement, feature_, vars_, false);
+ bool allow_overlap = get(sym_, keys::allow_overlap, feature_, vars_, false);
+ double opacity = get(sym_,keys::opacity, feature_, vars_, 1.0);
if (placement_method != MARKER_LINE_PLACEMENT ||
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 (!label::middle_point(path, x, y))
+ {
return;
+ }
}
else if (placement_method == MARKER_INTERIOR_PLACEMENT)
{
if (!label::interior_position(path, x, y))
+ {
return;
+ }
}
else
{
if (!label::centroid(path, x, y))
+ {
return;
+ }
}
agg::trans_affine matrix = marker_trans_;
matrix.translate(x,y);
@@ -149,8 +154,8 @@ struct vector_markers_rasterizer_dispatch
}
else
{
- double spacing = get(sym_, keys::spacing, 100.0);
- double max_error = get(sym_, keys::max_error, 0.2);
+ double spacing = get(sym_, keys::spacing, feature_, vars_, 100.0);
+ double max_error = get(sym_, keys::max_error, feature_, vars_, 0.2);
markers_placement placement(path, bbox_, marker_trans_, detector_,
spacing * scale_factor_,
max_error,
@@ -168,7 +173,6 @@ struct vector_markers_rasterizer_dispatch
}
}
private:
- agg::scanline_u8 sl_;
BufferType & buf_;
pixfmt_type pixf_;
renderer_base renb_;
@@ -178,6 +182,8 @@ private:
agg::trans_affine const& marker_trans_;
markers_symbolizer const& sym_;
Detector & detector_;
+ feature_impl & feature_;
+ attributes const& vars_;
double scale_factor_;
bool snap_to_pixels_;
};
@@ -198,6 +204,8 @@ struct raster_markers_rasterizer_dispatch
agg::trans_affine const& marker_trans,
markers_symbolizer const& sym,
Detector & detector,
+ feature_impl & feature,
+ attributes const& vars,
double scale_factor,
bool snap_to_pixels)
: buf_(render_buffer),
@@ -208,27 +216,22 @@ struct raster_markers_rasterizer_dispatch
marker_trans_(marker_trans),
sym_(sym),
detector_(detector),
+ feature_(feature),
+ vars_(vars),
scale_factor_(scale_factor),
snap_to_pixels_(snap_to_pixels)
{
- pixf_.comp_op(get(sym_, keys::comp_op, 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_)
- {
+ pixf_.comp_op(get(sym_, keys::comp_op, feature_, vars_, agg::comp_op_src_over));
}
template
void add_path(T & path)
{
- marker_placement_enum placement_method = get(sym_, keys::markers_placement_type, MARKER_POINT_PLACEMENT);
- bool allow_overlap = get(sym_, keys::allow_overlap, false);
+ marker_placement_enum placement_method = get(sym_, keys::markers_placement_type, feature_, vars_, MARKER_POINT_PLACEMENT);
+ bool allow_overlap = get(sym_, keys::allow_overlap, feature_, vars_, false);
box2d bbox_(0,0, src_.width(),src_.height());
- double opacity = get(sym_, keys::opacity, 1.0);
- bool ignore_placement = get(sym_, keys::ignore_placement, false);
+ double opacity = get(sym_, keys::opacity, feature_, vars_, 1.0);
+ bool ignore_placement = get(sym_, keys::ignore_placement, feature_, vars_, false);
if (placement_method != MARKER_LINE_PLACEMENT ||
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 (!label::middle_point(path, x, y))
+ {
return;
+ }
}
else if (placement_method == MARKER_INTERIOR_PLACEMENT)
{
if (!label::interior_position(path, x, y))
+ {
return;
+ }
}
else
{
if (!label::centroid(path, x, y))
+ {
return;
+ }
}
agg::trans_affine matrix = marker_trans_;
matrix.translate(x,y);
@@ -266,8 +275,8 @@ struct raster_markers_rasterizer_dispatch
}
else
{
- double spacing = get(sym_, keys::spacing, 100.0);
- double max_error = get(sym_, keys::max_error, 0.2);
+ double spacing = get(sym_, keys::spacing, feature_, vars_, 100.0);
+ double max_error = get(sym_, keys::max_error, feature_, vars_, 0.2);
markers_placement placement(path, bbox_, marker_trans_, detector_,
spacing * scale_factor_,
max_error,
@@ -287,6 +296,7 @@ struct raster_markers_rasterizer_dispatch
double opacity)
{
typedef agg::pixfmt_rgba32_pre pixfmt_pre;
+ agg::scanline_u8 sl_;
double width = src_.width();
double height = src_.height();
if (std::fabs(1.0 - scale_factor_) < 0.001
@@ -349,7 +359,6 @@ struct raster_markers_rasterizer_dispatch
}
private:
- agg::scanline_u8 sl_;
BufferType & buf_;
pixfmt_comp_type pixf_;
renderer_base renb_;
@@ -358,13 +367,15 @@ private:
agg::trans_affine const& marker_trans_;
markers_symbolizer const& sym_;
Detector & detector_;
+ feature_impl & feature_;
+ attributes const& vars_;
double scale_factor_;
bool snap_to_pixels_;
};
template
-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(sym, keys::width);
auto height_expr = get(sym, keys::height);
@@ -372,17 +383,17 @@ void build_ellipse(T const& sym, mapnik::feature_impl const& feature, svg_storag
double height = 0;
if (width_expr && height_expr)
{
- width = boost::apply_visitor(evaluate(feature), *width_expr).to_double();
- height = boost::apply_visitor(evaluate(feature), *height_expr).to_double();
+ width = boost::apply_visitor(evaluate(feature,vars), *width_expr).to_double();
+ height = boost::apply_visitor(evaluate(feature,vars), *height_expr).to_double();
}
else if (width_expr)
{
- width = boost::apply_visitor(evaluate(feature), *width_expr).to_double();
+ width = boost::apply_visitor(evaluate(feature,vars), *width_expr).to_double();
height = width;
}
else if (height_expr)
{
- height = boost::apply_visitor(evaluate(feature), *height_expr).to_double();
+ height = boost::apply_visitor(evaluate(feature,vars), *height_expr).to_double();
width = height;
}
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
-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(sym, keys::fill);
- auto fill_opacity = get_optional(sym, keys::fill_opacity);
- auto stroke_color = get_optional(sym, keys::stroke);
- auto stroke_width = get_optional(sym, keys::stroke_width);
- auto stroke_opacity = get_optional(sym, keys::stroke_opacity);
+ auto fill_color = get_optional(sym, keys::fill, feature, vars);
+ auto fill_opacity = get_optional(sym, keys::fill_opacity, feature, vars);
+ auto stroke_color = get_optional(sym, keys::stroke, feature, vars);
+ auto stroke_width = get_optional(sym, keys::stroke_width, feature, vars);
+ auto stroke_opacity = get_optional(sym, keys::stroke_opacity, feature, vars);
if (fill_color ||
fill_opacity ||
stroke_color ||
@@ -463,7 +477,8 @@ template
void setup_transform_scaling(agg::trans_affine & tr,
double svg_width,
double svg_height,
- mapnik::feature_impl const& feature,
+ mapnik::feature_impl & feature,
+ attributes const& vars,
T const& sym)
{
double width = 0;
@@ -471,11 +486,11 @@ void setup_transform_scaling(agg::trans_affine & tr,
expression_ptr width_expr = get(sym, keys::width);
if (width_expr)
- width = boost::apply_visitor(evaluate(feature), *width_expr).to_double();
+ width = boost::apply_visitor(evaluate(feature,vars), *width_expr).to_double();
expression_ptr height_expr = get(sym, keys::height);
if (height_expr)
- height = boost::apply_visitor(evaluate(feature), *height_expr).to_double();
+ height = boost::apply_visitor(evaluate(feature,vars), *height_expr).to_double();
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
template
-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();
if (geom_count == 1)
@@ -506,8 +521,8 @@ void apply_markers_multi(feature_impl & feature, Converter& converter, markers_s
}
else if (geom_count > 1)
{
- marker_multi_policy_enum multi_policy = get(sym, keys::markers_multipolicy, MARKER_EACH_MULTI);
- marker_placement_enum placement = get(sym, keys::markers_placement_type, MARKER_POINT_PLACEMENT);
+ marker_multi_policy_enum multi_policy = get(sym, keys::markers_multipolicy, feature, vars, MARKER_EACH_MULTI);
+ marker_placement_enum placement = get(sym, keys::markers_placement_type, feature, vars, MARKER_POINT_PLACEMENT);
if (placement == MARKER_POINT_PLACEMENT &&
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())
{
- converter.apply(path);
+ converter.apply(path);
}
}
}
diff --git a/include/mapnik/query.hpp b/include/mapnik/query.hpp
index 0b08be756..c903982cb 100644
--- a/include/mapnik/query.hpp
+++ b/include/mapnik/query.hpp
@@ -25,6 +25,7 @@
//mapnik
#include
+#include
// boost
#include
@@ -49,7 +50,8 @@ public:
scale_denominator_(scale_denominator),
filter_factor_(1.0),
unbuffered_bbox_(unbuffered_bbox),
- names_()
+ names_(),
+ vars_()
{}
query(box2d const& bbox,
@@ -60,7 +62,8 @@ public:
scale_denominator_(scale_denominator),
filter_factor_(1.0),
unbuffered_bbox_(bbox),
- names_()
+ names_(),
+ vars_()
{}
query(box2d const& bbox)
@@ -69,7 +72,8 @@ public:
scale_denominator_(1.0),
filter_factor_(1.0),
unbuffered_bbox_(bbox),
- names_()
+ names_(),
+ vars_()
{}
query(query const& other)
@@ -78,7 +82,8 @@ public:
scale_denominator_(other.scale_denominator_),
filter_factor_(other.filter_factor_),
unbuffered_bbox_(other.unbuffered_bbox_),
- names_(other.names_)
+ names_(other.names_),
+ vars_(other.vars_)
{}
query& operator=(query const& other)
@@ -90,6 +95,7 @@ public:
filter_factor_=other.filter_factor_;
unbuffered_bbox_=other.unbuffered_bbox_;
names_=other.names_;
+ vars_=other.vars_;
return *this;
}
@@ -143,6 +149,16 @@ public:
return names_;
}
+ void set_variables(attributes const& vars)
+ {
+ vars_ = vars;
+ }
+
+ attributes const& variables() const
+ {
+ return vars_;
+ }
+
private:
box2d bbox_;
resolution_type resolution_;
@@ -150,6 +166,7 @@ private:
double filter_factor_;
box2d unbuffered_bbox_;
std::set names_;
+ attributes vars_;
};
}
diff --git a/include/mapnik/renderer_common.hpp b/include/mapnik/renderer_common.hpp
index 62faab3b7..1e0af87cc 100644
--- a/include/mapnik/renderer_common.hpp
+++ b/include/mapnik/renderer_common.hpp
@@ -27,30 +27,33 @@
#include // for face_manager, etc
#include // for box2d
#include // for CoordTransform
+#include
// fwd declarations to speed up compile
namespace mapnik {
class label_collision_detector4;
class Map;
class request;
+// class attributes;
}
namespace mapnik {
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);
- 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,
std::shared_ptr 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);
- renderer_common(const renderer_common &);
+ renderer_common(renderer_common const& other);
unsigned width_;
unsigned height_;
double scale_factor_;
+ attributes vars_;
// TODO: dirty hack for cairo renderer, figure out how to remove this
std::shared_ptr shared_font_engine_;
freetype_engine &font_engine_;
@@ -61,7 +64,7 @@ struct renderer_common
private:
renderer_common(unsigned width, unsigned height, double scale_factor,
- CoordTransform &&t, std::shared_ptr detector);
+ attributes const& vars, CoordTransform &&t, std::shared_ptr detector);
};
}
diff --git a/include/mapnik/renderer_common/process_group_symbolizer.hpp b/include/mapnik/renderer_common/process_group_symbolizer.hpp
index ff6cf7663..68c378378 100644
--- a/include/mapnik/renderer_common/process_group_symbolizer.hpp
+++ b/include/mapnik/renderer_common/process_group_symbolizer.hpp
@@ -115,7 +115,8 @@ struct render_thunk_extractor : public boost::static_visitor<>
{
render_thunk_extractor(box2d &box,
render_thunk_list &thunks,
- mapnik::feature_impl &feature,
+ feature_impl &feature,
+ attributes const& vars,
proj_transform const &prj_trans,
renderer_common &common,
box2d const &clipping_extent);
@@ -137,7 +138,8 @@ private:
box2d &box_;
render_thunk_list &thunks_;
- mapnik::feature_impl &feature_;
+ feature_impl & feature_;
+ attributes const& vars_;
proj_transform const &prj_trans_;
renderer_common &common_;
box2d clipping_extent_;
@@ -181,9 +183,10 @@ void render_offset_placements(placements_list const& placements,
template
void render_group_symbolizer(group_symbolizer const &sym,
- mapnik::feature_impl &feature,
- proj_transform const &prj_trans,
- box2d const &clipping_extent,
+ feature_impl & feature,
+ attributes const& vars,
+ proj_transform const & prj_trans,
+ box2d const & clipping_extent,
renderer_common &common,
F render_thunks)
{
@@ -260,7 +263,7 @@ void render_group_symbolizer(group_symbolizer const &sym,
// get the layout for this set of properties
for (auto const& rule : props->get_rules())
{
- if (boost::apply_visitor(evaluate(*sub_feature),
+ if (boost::apply_visitor(evaluate(*sub_feature,common.vars_),
*(rule->get_filter())).to_bool())
{
// 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
bound_box bounds;
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);
for (auto const& sym : *rule)
@@ -288,7 +291,7 @@ void render_group_symbolizer(group_symbolizer const &sym,
}
// 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.scale_factor_, common.t_,
*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
if (rpt_key_expr)
{
- rpt_key_value = boost::apply_visitor(evaluate(*match_feature), *rpt_key_expr).to_unicode();
+ rpt_key_value = boost::apply_visitor(evaluate(*match_feature,common.vars_), *rpt_key_expr).to_unicode();
}
helper.add_box_element(layout_manager.offset_box_at(i), rpt_key_value);
}
diff --git a/include/mapnik/renderer_common/process_markers_symbolizer.hpp b/include/mapnik/renderer_common/process_markers_symbolizer.hpp
index c6bf5a2c0..8b04eb1cc 100644
--- a/include/mapnik/renderer_common/process_markers_symbolizer.hpp
+++ b/include/mapnik/renderer_common/process_markers_symbolizer.hpp
@@ -48,9 +48,9 @@ void render_markers_symbolizer(markers_symbolizer const &sym,
typedef boost::mpl::vector conv_types;
typedef agg::pod_bvector svg_attribute_type;
- std::string filename = get(sym, keys::file, feature, "shape://ellipse");
- bool clip = get(sym, keys::clip, feature, false);
- double smooth = get(sym, keys::smooth, feature, false);
+ std::string filename = get(sym, keys::file, feature, common.vars_, "shape://ellipse");
+ bool clip = get(sym, keys::clip, feature, common.vars_, false);
+ double smooth = get(sym, keys::smooth, feature, common.vars_, false);
// https://github.com/mapnik/mapnik/issues/1316
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;
vertex_stl_adapter stl_storage(marker_ellipse.source());
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;
- 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(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 bbox = marker_ellipse.bounding_box();
auto rasterizer_dispatch = make_vector_dispatch(
@@ -90,7 +90,7 @@ void render_markers_symbolizer(markers_symbolizer const &sym,
vertex_converter, dispatch_type, markers_symbolizer,
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)
{
geometry_type::types type = feature.paths()[0].type();
@@ -103,18 +103,18 @@ void render_markers_symbolizer(markers_symbolizer const &sym,
}
converter.template set(); //always transform
if (smooth > 0.0) converter.template set(); // optional smooth converter
- apply_markers_multi(feature, converter, sym);
+ apply_markers_multi(feature, common.vars_, converter, sym);
}
else
{
box2d 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(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 stl_storage((*stock_vector_marker)->source());
svg_path_adapter svg_path(stl_storage);
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(
svg_path, result ? attributes : (*stock_vector_marker)->attributes(),
**stock_vector_marker, bbox, tr, snap_pixels);
@@ -122,7 +122,7 @@ void render_markers_symbolizer(markers_symbolizer const &sym,
vertex_converter, dispatch_type, markers_symbolizer,
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)
{
geometry_type::types type = feature.paths()[0].type();
@@ -135,14 +135,14 @@ void render_markers_symbolizer(markers_symbolizer const &sym,
}
converter.template set(); //always transform
if (smooth > 0.0) converter.template set(); // optional smooth converter
- apply_markers_multi(feature, converter, sym);
+ apply_markers_multi(feature, common.vars_, converter, sym);
}
}
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(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 const& bbox = (*mark)->bounding_box();
boost::optional marker = (*mark)->get_bitmap_data();
@@ -151,7 +151,7 @@ void render_markers_symbolizer(markers_symbolizer const &sym,
vertex_converter, dispatch_type, markers_symbolizer,
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)
{
@@ -165,7 +165,7 @@ void render_markers_symbolizer(markers_symbolizer const &sym,
}
converter.template set(); //always transform
if (smooth > 0.0) converter.template set(); // optional smooth converter
- apply_markers_multi(feature, converter, sym);
+ apply_markers_multi(feature, common.vars_, converter, sym);
}
}
}
diff --git a/include/mapnik/renderer_common/process_point_symbolizer.hpp b/include/mapnik/renderer_common/process_point_symbolizer.hpp
index 0623730d9..e7cc3b5a7 100644
--- a/include/mapnik/renderer_common/process_point_symbolizer.hpp
+++ b/include/mapnik/renderer_common/process_point_symbolizer.hpp
@@ -36,9 +36,9 @@ void render_point_symbolizer(point_symbolizer const &sym,
renderer_common &common,
F render_marker)
{
- std::string filename = get(sym, keys::file, feature);
+ std::string filename = get(sym, keys::file, feature, common.vars_);
boost::optional marker;
- if ( !filename.empty() )
+ if (!filename.empty())
{
marker = marker_cache::instance().find(filename, true);
}
@@ -46,20 +46,19 @@ void render_point_symbolizer(point_symbolizer const &sym,
{
marker.reset(std::make_shared());
}
-
if (marker)
{
- double opacity = get(sym,keys::opacity,feature, 1.0);
- bool allow_overlap = get(sym, keys::allow_overlap, feature, false);
- bool ignore_placement = get(sym, keys::ignore_placement, feature, false);
- point_placement_enum placement= get(sym, keys::point_placement_type, feature, CENTROID_POINT_PLACEMENT);
+ double opacity = get(sym,keys::opacity,feature, common.vars_, 1.0);
+ bool allow_overlap = get(sym, keys::allow_overlap, feature, common.vars_, false);
+ bool ignore_placement = get(sym, keys::ignore_placement, feature, common.vars_, false);
+ point_placement_enum placement= get(sym, keys::point_placement_type, feature, common.vars_, CENTROID_POINT_PLACEMENT);
box2d const& bbox = (*marker)->bounding_box();
coord2d center = bbox.center();
agg::trans_affine tr;
auto image_transform = get_optional(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 recenter_tr = recenter * tr;
diff --git a/include/mapnik/renderer_common/process_polygon_symbolizer.hpp b/include/mapnik/renderer_common/process_polygon_symbolizer.hpp
index c3756a7a0..b65224ce3 100644
--- a/include/mapnik/renderer_common/process_polygon_symbolizer.hpp
+++ b/include/mapnik/renderer_common/process_polygon_symbolizer.hpp
@@ -36,15 +36,15 @@ void render_polygon_symbolizer(polygon_symbolizer const &sym,
{
agg::trans_affine tr;
auto transform = get_optional(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(sym, keys::clip, feature, true);
- double simplify_tolerance = get(sym, keys::simplify_tolerance, feature, 0.0);
- double smooth = get(sym, keys::smooth, feature, 0.0);
- double opacity = get(sym,keys::fill_opacity,feature, 1.0);
+ bool clip = get(sym, keys::clip, feature, common.vars_, true);
+ double simplify_tolerance = get(sym, keys::simplify_tolerance, feature, common.vars_, 0.0);
+ double smooth = get(sym, keys::smooth, feature, common.vars_, 0.0);
+ double opacity = get(sym,keys::fill_opacity,feature,common.vars_, 1.0);
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(); //optional clip (default: true)
converter.template set(); //always transform
@@ -60,7 +60,7 @@ void render_polygon_symbolizer(polygon_symbolizer const &sym,
}
}
- color const& fill = get(sym, keys::fill, feature, mapnik::color(128,128,128)); // gray
+ color const& fill = get(sym, keys::fill, feature, common.vars_, mapnik::color(128,128,128)); // gray
fill_func(fill, opacity);
}
diff --git a/include/mapnik/renderer_common/process_raster_symbolizer.hpp b/include/mapnik/renderer_common/process_raster_symbolizer.hpp
index dae91ecae..77798dcb8 100644
--- a/include/mapnik/renderer_common/process_raster_symbolizer.hpp
+++ b/include/mapnik/renderer_common/process_raster_symbolizer.hpp
@@ -23,6 +23,9 @@
#ifndef MAPNIK_RENDERER_COMMON_PROCESS_RASTER_SYMBOLIZER_HPP
#define MAPNIK_RENDERER_COMMON_PROCESS_RASTER_SYMBOLIZER_HPP
+// mapnik
+#include
+
// agg
#include "agg_rendering_buffer.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;
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(sym, keys::scaling, feature, SCALING_NEAR);
- composite_mode_e comp_op = get(sym, keys::comp_op, feature, src_over);
-
- double opacity = get(sym,keys::opacity,feature, 1.0);
+ scaling_method_e scaling_method = get(sym, keys::scaling, feature, common.vars_, SCALING_NEAR);
+ composite_mode_e comp_op = get(sym, keys::comp_op, feature, common.vars_, src_over);
+ double opacity = get(sym,keys::opacity,feature, common.vars_, 1.0);
bool premultiply_source = !source->premultiplied_alpha_;
- auto is_premultiplied = get_optional(sym, keys::premultiplied);
+ auto is_premultiplied = get_optional(sym, keys::premultiplied, feature, common.vars_);
if (is_premultiplied)
{
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_y = ext.miny() - start_y;
- unsigned mesh_size = static_cast(get(sym,keys::mesh_size,feature, 16));
+ raster target(target_ext, raster_width, raster_height, source->get_filter_factor());
+ unsigned mesh_size = static_cast