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
- 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

View file

@ -52,7 +52,7 @@
</Style>
<Style name="labels">
<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>
</Style>
<Layer name="layer"

View file

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

View file

@ -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)

View file

@ -21,6 +21,7 @@
*****************************************************************************/
#include "boost_std_shared_shim.hpp"
#include "python_to_value.hpp"
// boost
#include <boost/python.hpp>
@ -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<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
@ -86,8 +87,8 @@ void export_expression()
class_<mapnik::expr_node ,boost::noncopyable>("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_);
;

View file

@ -21,6 +21,7 @@
*****************************************************************************/
#include "boost_std_shared_shim.hpp"
#include "python_to_value.hpp"
#include <boost/python/args.hpp> // for keywords, arg, etc
#include <boost/python/converter/from_python.hpp>
#include <boost/python/def.hpp> // for def
@ -182,7 +183,18 @@ void render(mapnik::Map const& map,
python_unblock_auto_block b;
mapnik::agg_renderer<mapnik::image_32> 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<mapnik::image_32> 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<mapnik::cairo_ptr> 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"

View file

@ -21,6 +21,7 @@
*****************************************************************************/
#include "boost_std_shared_shim.hpp"
#include "python_to_value.hpp"
// boost
#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()
{
using namespace boost::python;
@ -85,5 +95,6 @@ void export_query()
return_value_policy<copy_const_reference>()) )
.add_property("property_names", make_function(&query::property_names,
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;
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<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"))
{
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<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"))
{
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<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"))
{
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<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"))
{
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<formatting::list_node>
/* 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(){

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>
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)
{
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<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)
{
@ -96,9 +96,9 @@ void set_join_caps(Symbolizer const& sym, PathType & stroke, Feature const& feat
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)
{
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<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)
{

View file

@ -73,7 +73,7 @@ public:
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);
// 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<double> clipping_extent() const
{
if (common_.t_.offset() > 0)

View file

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

View file

@ -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<label_collision_detector4> 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,

View file

@ -39,14 +39,16 @@
namespace mapnik
{
template <typename T0, typename T1>
template <typename T0, typename T1, typename T2>
struct evaluate : boost::static_visitor<T1>
{
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<T1>
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<T1>
}
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);
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<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<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_impl,value_type>(*feature),*expr);
value_type result = boost::apply_visitor(evaluate<feature_impl,value_type,attributes>(*feature,vars),*expr);
if (result.to_bool())
{
was_painted = true;

View file

@ -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<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>
void add_path(T & path)
{
marker_placement_enum placement_method = get<marker_placement_enum>(sym_, keys::markers_placement_type, MARKER_POINT_PLACEMENT);
bool ignore_placement = get<bool>(sym_, keys::ignore_placement, false);
bool allow_overlap = get<bool>(sym_, keys::allow_overlap, false);
double spacing = get<double>(sym_, keys::spacing, 100.0);
double max_error = get<double>(sym_, keys::max_error, 0.2);
agg::scanline_bin sl_;
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, feature_, vars_, false);
bool allow_overlap = get<bool>(sym_, keys::allow_overlap, feature_, vars_, false);
box2d<double> 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<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_,
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<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>
void add_path(T & path)
{
marker_placement_enum placement_method = get<marker_placement_enum>(sym_, keys::markers_placement_type, MARKER_POINT_PLACEMENT);
bool ignore_placement = get<bool>(sym_, keys::ignore_placement, false);
double spacing = get<double>(sym_, keys::spacing, 100.0);
double max_error = get<double>(sym_, keys::max_error, 0.2);
double opacity = get<double>(sym_,keys::opacity, 1.0);
bool allow_overlap = get<bool>(sym_, keys::allow_overlap, false);
agg::scanline_bin sl_;
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, feature_, vars_, false);
double opacity = get<double>(sym_,keys::opacity, feature_, vars_, 1.0);
bool allow_overlap = get<bool>(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<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_,
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

View file

@ -68,7 +68,7 @@ public:
typedef T buffer_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, 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<grid_rasterizer> ras_ptr;

View file

@ -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,

View file

@ -34,6 +34,7 @@
#include <mapnik/marker.hpp> // for svg_storage_type
#include <mapnik/svg/svg_storage.hpp>
#include <mapnik/markers_placement.hpp>
#include <mapnik/vertex_converters.hpp>
// 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<agg::comp_op_e>(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<agg::comp_op_e>(sym_, keys::comp_op, feature_, vars_, agg::comp_op_src_over));
}
template <typename T>
void add_path(T & path)
{
marker_placement_enum placement_method = get<marker_placement_enum>(sym_, keys::markers_placement_type, MARKER_POINT_PLACEMENT);
bool ignore_placement = get<bool>(sym_, keys::ignore_placement, false);
bool allow_overlap = get<bool>(sym_, keys::allow_overlap, false);
double opacity = get<double>(sym_,keys::opacity, 1.0);
agg::scanline_u8 sl_;
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, feature_, vars_, false);
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 ||
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<double>(sym_, keys::spacing, 100.0);
double max_error = get<double>(sym_, keys::max_error, 0.2);
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_,
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<agg::comp_op_e>(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<agg::comp_op_e>(sym_, keys::comp_op, feature_, vars_, agg::comp_op_src_over));
}
template <typename T>
void add_path(T & path)
{
marker_placement_enum placement_method = get<marker_placement_enum>(sym_, keys::markers_placement_type, MARKER_POINT_PLACEMENT);
bool allow_overlap = get<bool>(sym_, keys::allow_overlap, 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, feature_, vars_, false);
box2d<double> bbox_(0,0, src_.width(),src_.height());
double opacity = get<double>(sym_, keys::opacity, 1.0);
bool ignore_placement = get<bool>(sym_, keys::ignore_placement, false);
double opacity = get<double>(sym_, keys::opacity, feature_, vars_, 1.0);
bool ignore_placement = get<bool>(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<double>(sym_, keys::spacing, 100.0);
double max_error = get<double>(sym_, keys::max_error, 0.2);
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_,
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 <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 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;
if (width_expr && height_expr)
{
width = boost::apply_visitor(evaluate<feature_impl,value_type>(feature), *width_expr).to_double();
height = boost::apply_visitor(evaluate<feature_impl,value_type>(feature), *height_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,attributes>(feature,vars), *height_expr).to_double();
}
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;
}
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;
}
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>
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_opacity = get_optional<double>(sym, keys::fill_opacity);
auto stroke_color = get_optional<color>(sym, keys::stroke);
auto stroke_width = get_optional<double>(sym, keys::stroke_width);
auto stroke_opacity = get_optional<double>(sym, keys::stroke_opacity);
auto fill_color = get_optional<color>(sym, keys::fill, feature, vars);
auto fill_opacity = get_optional<double>(sym, keys::fill_opacity, feature, vars);
auto stroke_color = get_optional<color>(sym, keys::stroke, feature, vars);
auto stroke_width = get_optional<double>(sym, keys::stroke_width, feature, vars);
auto stroke_opacity = get_optional<double>(sym, keys::stroke_opacity, feature, vars);
if (fill_color ||
fill_opacity ||
stroke_color ||
@ -463,7 +477,8 @@ template <typename T>
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<expression_ptr>(sym, keys::width);
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);
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)
{
@ -497,7 +512,7 @@ void setup_transform_scaling(agg::trans_affine & tr,
// Apply markers to a feature with multiple geometries
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();
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<marker_multi_policy_enum>(sym, keys::markers_multipolicy, MARKER_EACH_MULTI);
marker_placement_enum placement = get<marker_placement_enum>(sym, keys::markers_placement_type, MARKER_POINT_PLACEMENT);
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, 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);
}
}
}

View file

@ -25,6 +25,7 @@
//mapnik
#include <mapnik/box2d.hpp>
#include <mapnik/attribute.hpp>
// boost
#include <boost/tuple/tuple.hpp>
@ -49,7 +50,8 @@ public:
scale_denominator_(scale_denominator),
filter_factor_(1.0),
unbuffered_bbox_(unbuffered_bbox),
names_()
names_(),
vars_()
{}
query(box2d<double> const& bbox,
@ -60,7 +62,8 @@ public:
scale_denominator_(scale_denominator),
filter_factor_(1.0),
unbuffered_bbox_(bbox),
names_()
names_(),
vars_()
{}
query(box2d<double> 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<double> bbox_;
resolution_type resolution_;
@ -150,6 +166,7 @@ private:
double filter_factor_;
box2d<double> unbuffered_bbox_;
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/box2d.hpp> // for box2d
#include <mapnik/ctrans.hpp> // for CoordTransform
#include <mapnik/attribute.hpp>
// 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<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);
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<freetype_engine> 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<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_list &thunks,
mapnik::feature_impl &feature,
feature_impl &feature,
attributes const& vars,
proj_transform const &prj_trans,
renderer_common &common,
box2d<double> const &clipping_extent);
@ -137,7 +138,8 @@ private:
box2d<double> &box_;
render_thunk_list &thunks_;
mapnik::feature_impl &feature_;
feature_impl & feature_;
attributes const& vars_;
proj_transform const &prj_trans_;
renderer_common &common_;
box2d<double> clipping_extent_;
@ -181,9 +183,10 @@ void render_offset_placements(placements_list const& placements,
template <typename F>
void render_group_symbolizer(group_symbolizer const &sym,
mapnik::feature_impl &feature,
proj_transform const &prj_trans,
box2d<double> const &clipping_extent,
feature_impl & feature,
attributes const& vars,
proj_transform const & prj_trans,
box2d<double> 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<Feature,value_type>(*sub_feature),
if (boost::apply_visitor(evaluate<Feature,value_type,attributes>(*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<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);
}

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 agg::pod_bvector<path_attributes> svg_attribute_type;
std::string filename = get<std::string>(sym, keys::file, feature, "shape://ellipse");
bool clip = get<value_bool>(sym, keys::clip, feature, false);
double smooth = get<value_double>(sym, keys::smooth, feature, false);
std::string filename = get<std::string>(sym, keys::file, feature, common.vars_, "shape://ellipse");
bool clip = get<value_bool>(sym, keys::clip, feature, common.vars_, false);
double smooth = get<value_double>(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<svg_path_storage> 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<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();
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,
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<transform_tag>(); //always transform
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
{
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);
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());
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<box2d<double>, 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<transform_tag>(); //always transform
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
{
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);
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();
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,
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<transform_tag>(); //always transform
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,
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;
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<mapnik::marker>());
}
if (marker)
{
double opacity = get<double>(sym,keys::opacity,feature, 1.0);
bool allow_overlap = get<bool>(sym, keys::allow_overlap, feature, false);
bool ignore_placement = get<bool>(sym, keys::ignore_placement, feature, false);
point_placement_enum placement= get<point_placement_enum>(sym, keys::point_placement_type, feature, CENTROID_POINT_PLACEMENT);
double opacity = get<double>(sym,keys::opacity,feature, common.vars_, 1.0);
bool allow_overlap = get<bool>(sym, keys::allow_overlap, feature, common.vars_, 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, common.vars_, CENTROID_POINT_PLACEMENT);
box2d<double> const& bbox = (*marker)->bounding_box();
coord2d center = bbox.center();
agg::trans_affine tr;
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 recenter_tr = recenter * tr;

View file

@ -36,15 +36,15 @@ void render_polygon_symbolizer(polygon_symbolizer const &sym,
{
agg::trans_affine tr;
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);
double simplify_tolerance = get<double>(sym, keys::simplify_tolerance, feature, 0.0);
double smooth = get<value_double>(sym, keys::smooth, feature, 0.0);
double opacity = get<value_double>(sym,keys::fill_opacity,feature, 1.0);
bool clip = get<value_bool>(sym, keys::clip, feature, common.vars_, true);
double simplify_tolerance = get<double>(sym, keys::simplify_tolerance, feature, common.vars_, 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,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<clip_poly_tag>(); //optional clip (default: true)
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);
}

View file

@ -23,6 +23,9 @@
#ifndef MAPNIK_RENDERER_COMMON_PROCESS_RASTER_SYMBOLIZER_HPP
#define MAPNIK_RENDERER_COMMON_PROCESS_RASTER_SYMBOLIZER_HPP
// mapnik
#include <mapnik/warp.hpp>
// 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<scaling_method_e>(sym, keys::scaling, feature, SCALING_NEAR);
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, src_over);
double opacity = get<double>(sym,keys::opacity,feature, 1.0);
scaling_method_e scaling_method = get<scaling_method_e>(sym, keys::scaling, feature, common.vars_, SCALING_NEAR);
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, common.vars_, 1.0);
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) 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<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,
*source,
prj_trans,
@ -88,31 +90,46 @@ void render_raster_symbolizer(raster_symbolizer const &sym,
offset_y,
mesh_size,
scaling_method);
composite(target.data_, comp_op, opacity, start_x, start_y);
}
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_,
source->data_,
0.0,
0.0);
composite(source->data_, comp_op, opacity, start_x, start_y);
}
else
{
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());
raster target(target_ext, raster_width, raster_height, source->get_filter_factor());
if (scaling_method == SCALING_BILINEAR8)
{
scale_image_bilinear8<image_data_32>(target.data_,
source->data_,
0.0,
0.0);
}
else
{
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:
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, 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();
void start_map_processing(Map const& map);
@ -147,6 +147,11 @@ public:
return common_.scale_factor_;
}
inline attributes const& variables() const
{
return common_.vars_;
}
inline OutputIterator& get_output_iterator()
{
return output_iterator_;

View file

@ -29,6 +29,7 @@
#include <mapnik/image_compositing.hpp>
#include <mapnik/simplify.hpp>
#include <mapnik/expression.hpp>
#include <mapnik/attribute.hpp>
#include <mapnik/expression_evaluator.hpp>
#include <mapnik/path_expression.hpp>
#include <mapnik/parse_path.hpp>
@ -38,6 +39,8 @@
#include <mapnik/text/placements/dummy.hpp>
#include <mapnik/raster_colorizer.hpp>
#include <mapnik/group/group_symbolizer_properties.hpp>
#include <mapnik/attribute.hpp>
// stl
#include <type_traits>
#include <algorithm>
@ -63,6 +66,7 @@ class feature_impl;
MAPNIK_DECL void evaluate_transform(agg::trans_affine& tr,
feature_impl const& feature,
attributes const& vars,
transform_type const& trans_expr,
double scale_factor=1.0);
@ -245,10 +249,10 @@ struct evaluate_expression_wrapper
{
typedef T result_type;
template <typename T1, typename T2>
result_type operator() (T1 const& expr, T2 const& feature) const
template <typename T1, typename T2, typename T3>
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);
}
};
@ -257,10 +261,10 @@ struct evaluate_expression_wrapper
template <>
struct evaluate_expression_wrapper<mapnik::color>
{
template <typename T1, typename T2>
mapnik::color operator() (T1 const& expr, T2 const& feature) const
template <typename T1, typename T2, typename T3>
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?
if (val.is_null()) return mapnik::color(255,192,203); // pink
return mapnik::color(val.to_string());
@ -271,10 +275,10 @@ struct evaluate_expression_wrapper<mapnik::color>
template <>
struct evaluate_expression_wrapper<mapnik::enumeration_wrapper>
{
template <typename T1, typename T2>
mapnik::enumeration_wrapper operator() (T1 const& expr, T2 const& feature) const
template <typename T1, typename T2, typename T3>
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());
}
};
@ -285,12 +289,14 @@ struct extract_value : public boost::static_visitor<T>
{
typedef T result_type;
extract_value(mapnik::feature_impl const& feature)
: feature_(feature) {}
extract_value(mapnik::feature_impl const& feature,
mapnik::attributes const& v)
: feature_(feature),
vars_(v) {}
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
@ -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);
}
template <typename T1>
auto operator() (T1 const& val) const -> result_type
template <typename TVal>
auto operator() (TVal const& val) const -> result_type
{
return result_type();
}
mapnik::feature_impl const& feature_;
mapnik::attributes const& vars_;
};
template <typename T1>
@ -353,25 +360,25 @@ bool has_key(symbolizer_base const& sym, keys key)
}
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;
const_iterator itr = sym.properties.find(key);
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;
}
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;
const_iterator itr = sym.properties.find(key);
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>();
}

View file

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

View file

@ -46,7 +46,7 @@ public:
virtual ~node() {}
virtual void to_xml(boost::property_tree::ptree &xml) const;
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;
};
} //ns formatting

View file

@ -40,7 +40,7 @@ class MAPNIK_DECL expression_format: public node {
public:
void to_xml(boost::property_tree::ptree &xml) const;
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;
void set_child(node_ptr child);

View file

@ -36,7 +36,7 @@ class MAPNIK_DECL format_node: public node {
public:
void to_xml(boost::property_tree::ptree &xml) const;
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;
void set_child(node_ptr child);

View file

@ -34,7 +34,7 @@ class MAPNIK_DECL layout_node: public node {
public:
void to_xml(boost::property_tree::ptree &xml) const;
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;
void set_child(node_ptr child);
node_ptr get_child() const;

View file

@ -35,7 +35,7 @@ class MAPNIK_DECL list_node: public node {
public:
list_node() : node(), children_() {}
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;
void push_back(node_ptr n);

View file

@ -36,7 +36,7 @@ public:
text_node(std::string text): node(), text_(parse_expression(text)) {}
void to_xml(boost::property_tree::ptree &xml) const;
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;
void set_text(expression_ptr text);

View file

@ -101,7 +101,7 @@ public:
pixel_position alignment_offset() 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:
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:
placement_finder(feature_impl const& feature,
attributes const& attr,
DetectorType & detector,
box2d<double> const& extent,
text_placement_info_ptr placement_info,
@ -79,6 +80,7 @@ private:
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);
feature_impl const& feature_;
attributes const& attr_;
DetectorType &detector_;
box2d<double> const& extent_;
text_placement_info_ptr info_;

View file

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

View file

@ -175,7 +175,7 @@ struct MAPNIK_DECL text_symbolizer_properties
/** 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.
*/
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. */
void set_old_style_expression(expression_ptr expr);
/** Sets new format tree. */

View file

@ -46,10 +46,11 @@ class feature_impl;
template <typename Container> struct expression_attributes;
template <typename T>
template <typename T, typename T1>
struct transform_processor
{
typedef T feature_type;
typedef T1 variable_type;
typedef agg::trans_affine transform_type;
template <typename Container>
@ -109,9 +110,11 @@ struct transform_processor
{
node_evaluator(transform_type& tr,
feature_type const& feat,
variable_type const& v,
double scale_factor)
: transform_(tr),
feature_(feat),
vars_(v),
scale_factor_(scale_factor) {}
void operator() (identity_node const& node)
@ -175,7 +178,7 @@ struct transform_processor
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();
}
@ -186,6 +189,7 @@ struct transform_processor
transform_type& transform_;
feature_type const& feature_;
variable_type const& vars_;
double scale_factor_;
};
@ -201,10 +205,13 @@ struct transform_processor
}
}
static void evaluate(transform_type& tr, feature_type const& feat,
transform_list const& list, double scale_factor)
static void evaluate(transform_type& tr,
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
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

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);
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);
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)));
geom.set_simplify_tolerance(get<value_double>(sym, keys::simplify_tolerance, feat));
auto const& vars = boost::fusion::at_c<7>(args);
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)
{
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);
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);
auto const& feat = boost::fusion::at_c<6>(args);
set_join_caps(sym, geom, feat);
double miterlimit = get<value_double>(sym, keys::stroke_miterlimit, feat, 4.0);
auto const& vars = boost::fusion::at_c<7>(args);
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);
double scale_factor = boost::fusion::at_c<7>(args);
double width = get<value_double>(sym, keys::stroke_width, feat, 1.0);
double scale_factor = boost::fusion::at_c<8>(args);
double width = get<value_double>(sym, keys::stroke_width, feat, vars, 1.0);
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);
auto const& feat = boost::fusion::at_c<6>(args);
double offset = get<value_double>(sym, keys::offset, feat);
double scale_factor = boost::fusion::at_c<7>(args);
auto const& vars = 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);
}
};
@ -351,6 +355,7 @@ struct vertex_converter : private mapnik::noncopyable
proj_trans_type const&,
affine_trans_type const&,
feature_type const&,
attributes const&,
double //scale-factor
> args_type;
@ -361,6 +366,7 @@ struct vertex_converter : private mapnik::noncopyable
proj_trans_type const& prj_trans,
affine_trans_type const& affine_trans,
feature_type const& feature,
attributes const& vars,
double scale_factor)
: disp_(args_type(boost::cref(b),
boost::ref(ras),
@ -369,6 +375,7 @@ struct vertex_converter : private mapnik::noncopyable
boost::cref(prj_trans),
boost::cref(affine_trans),
boost::cref(feature),
boost::cref(vars),
scale_factor)) {}
template <typename Geometry>

View file

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

View file

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

View file

@ -38,6 +38,7 @@
// boost
#include <boost/algorithm/string.hpp>
#include <boost/tokenizer.hpp>
#include <boost/regex.hpp>
// stl
#include <memory>
@ -85,9 +86,11 @@ postgis_datasource::postgis_datasource(parameters const& params)
extent_from_subquery_(*params.get<mapnik::boolean>("extent_from_subquery", false)),
max_async_connections_(*params_.get<mapnik::value_integer>("max_async_connection", 1)),
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
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_min_scale_(*params.get<mapnik::value_integer>("intersect_min_scale", 0)),
intersect_max_scale_(*params.get<mapnik::value_integer>("intersect_max_scale", 0))
{
#ifdef MAPNIK_STATS
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_))
{
std::ostringstream ss;
ss << 0;
boost::algorithm::replace_all(populated_sql, pixel_width_token_, ss.str());
boost::algorithm::replace_all(populated_sql, pixel_width_token_, "0");
}
if (boost::algorithm::icontains(sql, pixel_height_token_))
{
std::ostringstream ss;
ss << 0;
boost::algorithm::replace_all(populated_sql, pixel_height_token_, ss.str());
boost::algorithm::replace_all(populated_sql, pixel_height_token_, "0");
}
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;
}
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 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_))
{
boost::algorithm::replace_all(populated_sql, bbox_token_, box);
return populated_sql;
}
else
{
@ -582,9 +596,27 @@ std::string postgis_datasource::populate_tokens(std::string const& sql, double s
{
s << " WHERE \"" << geometryColumn_ << "\" && " << box;
}
return populated_sql + s.str();
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;
@ -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);
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;

View file

@ -33,9 +33,11 @@
#include <mapnik/feature_layer_desc.hpp>
#include <mapnik/unicode.hpp>
#include <mapnik/value_types.hpp>
#include <mapnik/attribute.hpp>
// boost
#include <boost/optional.hpp>
#include <boost/regex.hpp>
// stl
#include <memory>
@ -77,7 +79,12 @@ public:
private:
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::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;
@ -112,6 +119,7 @@ private:
bool estimate_extent_;
int max_async_connections_;
bool asynchronous_request_;
boost::regex pattern_;
int intersect_min_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),
gamma_method_(GAMMA_POWER),
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);
}
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),
pixmap_(pixmap),
internal_buffer_(),
@ -87,7 +87,7 @@ agg_renderer<T0,T1>::agg_renderer(Map const& m, request const& req, T0 & pixmap,
ras_ptr(new rasterizer),
gamma_method_(GAMMA_POWER),
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);
}
@ -103,7 +103,7 @@ agg_renderer<T0,T1>::agg_renderer(Map const& m, T0 & pixmap, std::shared_ptr<T1>
ras_ptr(new rasterizer),
gamma_method_(GAMMA_POWER),
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);
}

View file

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

View file

@ -53,7 +53,7 @@ void agg_renderer<T0,T1>::process(debug_symbolizer const& sym,
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)
{

View file

@ -106,7 +106,7 @@ void agg_renderer<T0,T1>::process(group_symbolizer const& sym,
proj_transform const& prj_trans)
{
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)
{
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::rasterizer_outline_aa<renderer_type> rasterizer_type;
std::string filename = get<std::string>(sym, keys::file, feature);
boost::optional<marker_ptr> mark = marker_cache::instance().find(filename,true);
std::string filename = get<std::string>(sym, keys::file, feature, common_.vars_);
if (filename.empty()) return;
boost::optional<mapnik::marker_ptr> mark = marker_cache::instance().find(filename, true);
if (!mark) return;
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();
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 opacity = get<value_double>(sym,keys::stroke_opacity,feature, 1.0); TODO
double offset = get<value_double>(sym, keys::offset, feature, 0.0);
double simplify_tolerance = get<value_double>(sym, keys::simplify_tolerance, feature, 0.0);
double smooth = get<value_double>(sym, keys::smooth, feature, false);
double offset = get<value_double>(sym, keys::offset, feature, common_.vars_, 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, common_.vars_, false);
agg::rendering_buffer buf(current_buffer_->raw_data(),current_buffer_->width(),current_buffer_->height(), current_buffer_->width() * 4);
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);
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;
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();
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;
vertex_converter<box2d<double>, rasterizer_type, line_pattern_symbolizer,
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)
converter.set<transform_tag>(); //always transform

View file

@ -26,7 +26,6 @@
#include <mapnik/agg_renderer.hpp>
#include <mapnik/agg_helpers.hpp>
#include <mapnik/agg_rasterizer.hpp>
#include <mapnik/symbolizer.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)
{
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 g=col.green();
unsigned b=col.blue();
unsigned a=col.alpha();
double gamma = get<value_double>(sym, keys::stroke_gamma, feature, 1.0);
gamma_method_enum gamma_method = get<gamma_method_enum>(sym, keys::stroke_gamma_method, feature, GAMMA_POWER);
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, common_.vars_, GAMMA_POWER);
ras_ptr->reset();
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;
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);
agg::trans_affine tr;
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();
bool clip = get<value_bool>(sym, keys::clip, feature, true);
double width = get<value_double>(sym, keys::stroke_width, feature, 1.0);
double opacity = get<value_double>(sym,keys::stroke_opacity,feature, 1.0);
double offset = get<value_double>(sym, keys::offset, feature, 0.0);
double simplify_tolerance = get<value_double>(sym, keys::simplify_tolerance, feature, 0.0);
double smooth = get<value_double>(sym, keys::smooth, feature, false);
line_rasterizer_enum rasterizer_e = get<line_rasterizer_enum>(sym, keys::line_rasterizer, feature, RASTERIZER_FULL);
bool clip = get<value_bool>(sym, keys::clip, feature, common_.vars_, true);
double width = get<value_double>(sym, keys::stroke_width, feature, common_.vars_, 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, common_.vars_, 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, common_.vars_, false);
line_rasterizer_enum rasterizer_e = get<line_rasterizer_enum>(sym, keys::line_rasterizer, feature, common_.vars_, RASTERIZER_FULL);
if (clip)
{
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);
ren.color(agg::rgba8_pre(r, g, b, int(a * opacity)));
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,
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)
converter.set<transform_tag>(); // always transform
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,
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)
converter.set<transform_tag>(); // always transform

View file

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

View file

@ -25,7 +25,6 @@
#include <mapnik/agg_renderer.hpp>
#include <mapnik/agg_rasterizer.hpp>
#include <mapnik/image_util.hpp>
#include <mapnik/geom_util.hpp>
#include <mapnik/symbolizer.hpp>
#include <mapnik/marker.hpp>
@ -50,7 +49,7 @@ void agg_renderer<T0,T1>::process(point_symbolizer const& sym,
mapnik::feature_impl & feature,
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(
sym, feature, prj_trans, common_,

View file

@ -20,9 +20,6 @@
*
*****************************************************************************/
// boost
// mapnik
#include <mapnik/feature.hpp>
#include <mapnik/debug.hpp>
@ -57,13 +54,27 @@ void agg_renderer<T0,T1>::process(polygon_pattern_symbolizer const& sym,
mapnik::feature_impl & feature,
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 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);
ras_ptr->reset();
double gamma = get<value_double>(sym, keys::gamma, feature, 1.0);
gamma_method_enum gamma_method = get<gamma_method_enum>(sym, keys::gamma_method, feature, GAMMA_POWER);
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, common_.vars_, GAMMA_POWER);
if (gamma != gamma_ || gamma_method != 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;
}
std::string filename = get<std::string>(sym, keys::file, feature);
boost::optional<mapnik::marker_ptr> marker;
if ( !filename.empty() )
{
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);
bool clip = get<value_bool>(sym, keys::clip, feature, common_.vars_, false);
double opacity = get<double>(sym,keys::stroke_opacity, feature, common_.vars_, 1.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, common_.vars_, false);
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;
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);
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);
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_y=0;
@ -156,12 +143,12 @@ void agg_renderer<T0,T1>::process(polygon_pattern_symbolizer const& sym,
agg::trans_affine tr;
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;
vertex_converter<box2d<double>, rasterizer, polygon_pattern_symbolizer,
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)
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;
ras_ptr->reset();
double gamma = get<value_double>(sym, keys::gamma, feature, 1.0);
gamma_method_enum gamma_method = get<gamma_method_enum>(sym, keys::gamma_method, feature, GAMMA_POWER);
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, common_.vars_, GAMMA_POWER);
if (gamma != gamma_ || gamma_method != 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_scanline_aa_solid<renderer_base> renderer_type;
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_type ren(renb);
ren.color(agg::rgba8_pre(r, g, b, int(a * opacity)));

View file

@ -33,7 +33,6 @@
#include <mapnik/image_util.hpp>
#include <mapnik/raster.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/warp.hpp>
#include <mapnik/config.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(
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) {
composite(current_buffer_->data(), target.data_,
composite(current_buffer_->data(), target,
comp_op, opacity, start_x, start_y, false);
});
}
);
}
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();
text_symbolizer_helper helper(
sym, feature, prj_trans,
sym, feature, common_.vars_, prj_trans,
common_.width_, common_.height_,
common_.scale_factor_,
common_.t_, common_.font_manager_, *common_.detector_,
clip_box);
halo_rasterizer_enum halo_rasterizer = get<halo_rasterizer_enum>(sym, keys::halo_rasterizer, HALO_RASTERIZER_FULL);
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, src_over);
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, common_.vars_, src_over);
agg_text_renderer<T0> ren(*current_buffer_,
halo_rasterizer,
comp_op,
common_.scale_factor_,
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();
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();
text_symbolizer_helper helper(
sym, feature, prj_trans,
sym, feature, common_.vars_, prj_trans,
common_.width_, common_.height_,
common_.scale_factor_,
common_.t_, common_.font_manager_, *common_.detector_,
clip_box);
halo_rasterizer_enum halo_rasterizer = get<halo_rasterizer_enum>(sym, keys::halo_rasterizer, HALO_RASTERIZER_FULL);
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, src_over);
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, common_.vars_, src_over);
agg_text_renderer<T0> ren(*current_buffer_,
halo_rasterizer,
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);
if (transform)
{
evaluate_transform(halo_transform, feature, *transform);
evaluate_transform(halo_transform, feature, common_.vars_, *transform);
ren.set_halo_transform(halo_transform);
}
placements_list const& placements = helper.get();

View file

@ -58,6 +58,7 @@
#include <mapnik/attribute_collector.hpp>
#include <mapnik/group/group_layout_manager.hpp>
#include <mapnik/group/group_symbolizer_helper.hpp>
#include <mapnik/attribute.hpp>
// mapnik symbolizer generics
#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_ptr const& cairo,
attributes const& vars,
double scale_factor,
unsigned offset_x,
unsigned offset_y)
: m_(m),
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_)
{
setup(m);
@ -122,12 +124,13 @@ cairo_renderer_base::cairo_renderer_base(Map const& m,
cairo_renderer_base::cairo_renderer_base(Map const& m,
request const& req,
cairo_ptr const& cairo,
attributes const& vars,
double scale_factor,
unsigned offset_x,
unsigned offset_y)
: m_(m),
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_)
{
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_ptr const& cairo,
attributes const& vars,
std::shared_ptr<label_collision_detector4> detector,
double scale_factor,
unsigned offset_x,
unsigned offset_y)
: m_(m),
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_)
{
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 <>
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),
cairo_renderer_base(m,cairo,scale_factor,offset_x,offset_y) {}
cairo_renderer_base(m,cairo,attributes(),scale_factor,offset_x,offset_y) {}
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)
: 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 <>
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),
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 <>
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),
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 <>
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),
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 <>
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),
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() {}
@ -279,7 +283,7 @@ void cairo_renderer_base::process(polygon_symbolizer const& sym,
conv_types, feature_impl> vertex_converter_type;
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);
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;
cairo_save_restore guard(context_);
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, src_over);
mapnik::color fill = get<mapnik::color>(sym, keys::fill, feature);
double opacity = get<double>(sym, keys::fill_opacity, feature, 1.0);
double height = get<double>(sym, keys::height, feature, 0.0);
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, common_.vars_, mapnik::color(128,128,128));
double opacity = get<double>(sym, keys::fill_opacity, feature, common_.vars_, 1.0);
double height = get<double>(sym, keys::height, feature, common_.vars_, 0.0);
context_.set_operator(comp_op);
@ -340,21 +344,19 @@ void cairo_renderer_base::process(line_symbolizer const& sym,
offset_transform_tag,
dash_tag, stroke_tag> conv_types;
cairo_save_restore guard(context_);
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, src_over);
auto geom_transform = get_optional<transform_type>(sym, keys::geometry_transform);
bool clip = get<bool>(sym, keys::clip, feature, true);
double offset = get<double>(sym, keys::offset, feature, 0.0);
double simplify_tolerance = get<double>(sym, keys::simplify_tolerance, feature, 0.0);
double smooth = get<double>(sym, keys::smooth, feature, 0.0);
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, common_.vars_, src_over);
bool clip = get<bool>(sym, keys::clip, feature, common_.vars_, true);
double offset = get<double>(sym, keys::offset, feature, common_.vars_, 0.0);
double simplify_tolerance = get<double>(sym, keys::simplify_tolerance, feature, common_.vars_, 0.0);
double smooth = get<double>(sym, keys::smooth, feature, common_.vars_, 0.0);
mapnik::color stroke = get<mapnik::color>(sym, keys::stroke, feature, mapnik::color(0,0,0));
double stroke_opacity = get<double>(sym, keys::stroke_opacity, feature, 1.0);
line_join_enum stroke_join = get<line_join_enum>(sym, keys::stroke_linejoin, MITER_JOIN);
line_cap_enum stroke_cap = get<line_cap_enum>(sym, keys::stroke_linecap, BUTT_CAP);
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, common_.vars_, 1.0);
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, feature, common_.vars_, BUTT_CAP);
auto dash = get_optional<dash_array>(sym, keys::stroke_dasharray);
double miterlimit = get<double>(sym, keys::stroke_miterlimit, feature, 4.0);
double width = get<double>(sym, keys::stroke_width, feature, 1.0);
double miterlimit = get<double>(sym, keys::stroke_miterlimit, feature, common_.vars_, 4.0);
double width = get<double>(sym, keys::stroke_width, feature, common_.vars_, 1.0);
context_.set_operator(comp_op);
context_.set_color(stroke, stroke_opacity);
@ -368,7 +370,8 @@ void cairo_renderer_base::process(line_symbolizer const& sym,
}
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_;
if (clip)
@ -384,7 +387,7 @@ void cairo_renderer_base::process(line_symbolizer const& sym,
}
vertex_converter<box2d<double>, cairo_context, line_symbolizer,
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)
converter.set<transform_tag>(); // always transform
@ -553,7 +556,7 @@ void cairo_renderer_base::process(point_symbolizer const& sym,
mapnik::feature_impl & feature,
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_);
context_.set_operator(comp_op);
@ -571,15 +574,15 @@ void cairo_renderer_base::process(shield_symbolizer const& sym,
proj_transform const& prj_trans)
{
text_symbolizer_helper helper(
sym, feature, prj_trans,
sym, feature, common_.vars_, prj_trans,
common_.width_, common_.height_,
common_.scale_factor_,
common_.t_, common_.font_manager_, *common_.detector_,
common_.query_extent_);
cairo_save_restore guard(context_);
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, src_over);
double opacity = get<double>(sym,keys::opacity,feature, 1.0);
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, common_.vars_, 1.0);
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 coord_transform<CoordTransform,clipped_geometry_type> path_type;
std::string filename = get<std::string>(sym, keys::file, feature);
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, src_over);
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, common_.vars_, src_over);
boost::optional<marker_ptr> marker;
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;
cairo_save_restore guard(context_);
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, src_over);
std::string filename = get<std::string>(sym, keys::file, feature);
auto geom_transform = get_optional<transform_type>(sym, keys::geometry_transform);
bool clip = get<bool>(sym, keys::clip, feature, false);
double simplify_tolerance = get<double>(sym, keys::simplify_tolerance, feature, 0.0);
double smooth = get<double>(sym, keys::smooth, feature, 0.0);
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, common_.vars_);
bool clip = get<bool>(sym, keys::clip, feature, common_.vars_, true);
double simplify_tolerance = get<double>(sym, keys::simplify_tolerance, feature, common_.vars_, 0.0);
double smooth = get<double>(sym, keys::smooth, feature, common_.vars_, 0.0);
context_.set_operator(comp_op);
@ -728,12 +730,13 @@ void cairo_renderer_base::process(polygon_pattern_symbolizer const& sym,
//}
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;
vertex_converter<box2d<double>, cairo_context, polygon_pattern_symbolizer,
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)
converter.set<transform_tag>(); //always transform
@ -758,14 +761,14 @@ void cairo_renderer_base::process(raster_symbolizer const& sym,
proj_transform const& prj_trans)
{
cairo_save_restore guard(context_);
render_raster_symbolizer(
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) {
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 {
@ -780,6 +783,8 @@ struct markers_dispatch
markers_symbolizer const& sym,
box2d<double> const& bbox,
agg::trans_affine const& marker_trans,
feature_impl const& feature,
mapnik::attributes const& vars,
double scale_factor)
:ctx_(ctx),
marker_(marker),
@ -788,19 +793,20 @@ struct markers_dispatch
sym_(sym),
bbox_(bbox),
marker_trans_(marker_trans),
feature_(feature),
vars_(vars),
scale_factor_(scale_factor) {}
template <typename T>
void add_path(T & path)
{
marker_placement_enum placement_method = get<marker_placement_enum>(sym_, keys::markers_placement_type, MARKER_POINT_PLACEMENT);
bool ignore_placement = get<bool>(sym_, keys::ignore_placement, false);
bool allow_overlap = get<bool>(sym_, keys::allow_overlap, false);
double opacity = get<double>(sym_, keys::opacity, 1.0);
double spacing = get<double>(sym_, keys::spacing, 100.0);
double max_error = get<double>(sym_, keys::max_error, 0.2);
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, feature_, vars_, false);
bool allow_overlap = get<bool>(sym_, keys::allow_overlap, feature_, vars_, false);
double opacity = get<double>(sym_, keys::opacity, feature_, vars_, 1.0);
double spacing = get<double>(sym_, keys::spacing, feature_, vars_, 100.0);
double max_error = get<double>(sym_, keys::max_error, feature_, vars_, 0.2);
if (placement_method != MARKER_LINE_PLACEMENT ||
path.type() == geometry_type::types::Point)
@ -864,6 +870,8 @@ struct markers_dispatch
markers_symbolizer const& sym_;
box2d<double> const& bbox_;
agg::trans_affine const& marker_trans_;
feature_impl const& feature_;
attributes const& vars_;
double scale_factor_;
};
@ -876,6 +884,8 @@ struct markers_dispatch_2
markers_symbolizer const& sym,
box2d<double> const& bbox,
agg::trans_affine const& marker_trans,
feature_impl const& feature,
mapnik::attributes const& vars,
double scale_factor)
:ctx_(ctx),
marker_(marker),
@ -883,18 +893,20 @@ struct markers_dispatch_2
sym_(sym),
bbox_(bbox),
marker_trans_(marker_trans),
feature_(feature),
vars_(vars),
scale_factor_(scale_factor) {}
template <typename T>
void add_path(T & path)
{
marker_placement_enum placement_method = get<marker_placement_enum>(sym_, keys::markers_placement_type, MARKER_POINT_PLACEMENT);
double opacity = get<double>(sym_, keys::opacity, 1.0);
double spacing = get<double>(sym_, keys::spacing, 100.0);
double max_error = get<double>(sym_, keys::max_error, 0.2);
bool allow_overlap = get<bool>(sym_, keys::allow_overlap, false);
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 opacity = get<double>(sym_, keys::opacity, feature_, vars_, 1.0);
double spacing = get<double>(sym_, keys::spacing, feature_, vars_, 100.0);
double max_error = get<double>(sym_, keys::max_error, feature_, vars_, 0.2);
bool allow_overlap = get<bool>(sym_, keys::allow_overlap, feature_, vars_, false);
bool ignore_placement = get<bool>(sym_, keys::ignore_placement, feature_, vars_, false);
if (placement_method != MARKER_LINE_PLACEMENT ||
path.type() == geometry_type::types::Point)
@ -958,6 +970,8 @@ struct markers_dispatch_2
markers_symbolizer const& sym_;
box2d<double> const& bbox_;
agg::trans_affine const& marker_trans_;
feature_impl const& feature_;
attributes const& vars_;
double scale_factor_;
};
@ -973,7 +987,7 @@ void cairo_renderer_base::process(markers_symbolizer const& sym,
label_collision_detector4> vector_dispatch_type;
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);
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,
bool) -> vector_dispatch_type {
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,
box2d<double> const &bbox) -> raster_dispatch_type {
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)
{
text_symbolizer_helper helper(
sym, feature, prj_trans,
sym, feature, common_.vars_, prj_trans,
common_.width_, common_.height_,
common_.scale_factor_,
common_.t_, common_.font_manager_, *common_.detector_,
common_.query_extent_);
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);
placements_list const &placements = helper.get();
@ -1085,7 +1098,7 @@ void cairo_renderer_base::process(group_symbolizer const& sym,
proj_transform const& prj_trans)
{
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)
{
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;
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_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),
// NOTE: can change this to m dims instead of pixmap_ if render-time
// 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);
}
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),
pixmap_(pixmap),
ras_ptr(new grid_rasterizer),
// NOTE: can change this to m dims instead of pixmap_ if render-time
// 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);
}

View file

@ -68,7 +68,7 @@ void grid_renderer<T>::process(building_symbolizer const& sym,
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(
feature, height,

View file

@ -117,7 +117,7 @@ void grid_renderer<T>::process(group_symbolizer const& sym,
proj_transform const& prj_trans)
{
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)
{
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,
proj_transform const& prj_trans)
{
std::string filename = get<std::string>(sym, keys::file, feature);
boost::optional<marker_ptr> mark = marker_cache::instance().find(filename,true);
std::string filename = get<std::string>(sym, keys::file, feature, common_.vars_);
if (filename.empty()) return;
boost::optional<mapnik::marker_ptr> mark = marker_cache::instance().find(filename, true);
if (!mark) return;
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();
if (!pat) return;
bool clip = get<value_bool>(sym, keys::clip, feature);
double offset = get<value_double>(sym, keys::offset, feature, 0.0);
double simplify_tolerance = get<value_double>(sym, keys::simplify_tolerance, feature, 0.0);
double smooth = get<value_double>(sym, keys::smooth, feature, false);
bool clip = get<value_bool>(sym, keys::clip, feature, common_.vars_, true);
double offset = get<value_double>(sym, keys::offset, feature, common_.vars_, 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, common_.vars_, false);
typedef typename grid_renderer_base_type::pixfmt_type pixfmt_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;
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_;
if (clip)
@ -117,7 +120,7 @@ void grid_renderer<T>::process(line_pattern_symbolizer const& sym,
vertex_converter<box2d<double>, grid_rasterizer, line_symbolizer,
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)
converter.set<transform_tag>(); // always transform
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;
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_;
bool clip = get<value_bool>(sym, keys::clip, feature, true);
double width = get<value_double>(sym, keys::stroke_width, feature, 1.0);
double offset = get<value_double>(sym, keys::offset, feature, 0.0);
double simplify_tolerance = get<value_double>(sym, keys::simplify_tolerance, feature, 0.0);
double smooth = get<value_double>(sym, keys::smooth, feature, false);
bool clip = get<value_bool>(sym, keys::clip, feature, common_.vars_, true);
double width = get<value_double>(sym, keys::stroke_width, feature, common_.vars_,1.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, common_.vars_,0.0);
double smooth = get<value_double>(sym, keys::smooth, feature, common_.vars_,false);
bool has_dash = has_key<dash_array>(sym, keys::stroke_dasharray);
if (clip)
@ -90,7 +93,7 @@ void grid_renderer<T>::process(line_symbolizer const& sym,
vertex_converter<box2d<double>, grid_rasterizer, line_symbolizer,
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)
converter.set<transform_tag>(); // always transform
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_.scale_factor_,
feature,
common_.vars_,
pixmap_);
},
[&](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_.scale_factor_,
feature,
common_.vars_,
pixmap_);
});
}

View file

@ -52,7 +52,7 @@ void grid_renderer<T>::process(point_symbolizer const& sym,
mapnik::feature_impl & feature,
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(
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,
proj_transform const& prj_trans)
{
std::string filename = get<std::string>(sym, keys::file, feature);
boost::optional<marker_ptr> mark = marker_cache::instance().find(filename,true);
std::string filename = get<std::string>(sym, keys::file, feature, common_.vars_);
if (filename.empty()) return;
boost::optional<mapnik::marker_ptr> mark = marker_cache::instance().find(filename, true);
if (!mark) return;
if (!(*mark)->is_bitmap())
@ -68,18 +68,21 @@ void grid_renderer<T>::process(polygon_pattern_symbolizer const& sym,
ras_ptr->reset();
bool clip = get<value_bool>(sym, keys::clip, feature, false);
double simplify_tolerance = get<value_double>(sym, keys::simplify_tolerance, feature, 0.0);
double smooth = get<value_double>(sym, keys::smooth, 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, common_.vars_, 0.0);
double smooth = get<value_double>(sym, keys::smooth, feature, common_.vars_, false);
agg::trans_affine tr;
auto geom_transform = get_optional<transform_type>(sym, keys::geometry_transform);
if (geom_transform) evaluate_transform(tr, feature, *geom_transform, common_.scale_factor_);
auto transform = get_optional<transform_type>(sym, keys::geometry_transform);
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;
vertex_converter<box2d<double>, grid_rasterizer, polygon_pattern_symbolizer,
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)
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)
{
text_symbolizer_helper helper(
sym, feature, prj_trans,
sym, feature, common_.vars_, prj_trans,
common_.width_, common_.height_,
common_.scale_factor_,
common_.t_, common_.font_manager_, *common_.detector_,
common_.query_extent_);
bool placement_found = false;
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, src_over);
double opacity = get<double>(sym,keys::opacity,feature, 1.0);
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, common_.vars_, 1.0);
grid_text_renderer<T> ren(pixmap_,
comp_op,

View file

@ -37,14 +37,14 @@ void grid_renderer<T>::process(text_symbolizer const& sym,
proj_transform const& prj_trans)
{
text_symbolizer_helper helper(
sym, feature, prj_trans,
sym, feature, common_.vars_, prj_trans,
common_.width_, common_.height_,
common_.scale_factor_ * (1.0/pixmap_.get_resolution()),
common_.t_, common_.font_manager_, *common_.detector_,
common_.query_extent_);
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_,
comp_op,

View file

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

View file

@ -24,14 +24,18 @@
#include <mapnik/label_collision_detector.hpp>
#include <mapnik/map.hpp>
#include <mapnik/request.hpp>
#include <mapnik/attribute.hpp>
namespace mapnik {
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),
height_(height),
scale_factor_(scale_factor),
vars_(vars),
shared_font_engine_(std::make_shared<freetype_engine>()),
font_engine_(*shared_font_engine_),
font_manager_(font_engine_),
@ -40,26 +44,29 @@ renderer_common::renderer_common(unsigned width, unsigned height, double scale_f
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)
: renderer_common(width, height, scale_factor,
vars,
CoordTransform(m.width(),m.height(),m.get_current_extent(),offset_x,offset_y),
std::make_shared<label_collision_detector4>(
box2d<double>(-m.buffer_size(), -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,
std::shared_ptr<label_collision_detector4> detector)
: renderer_common(width, height, scale_factor,
vars,
CoordTransform(m.width(),m.height(),m.get_current_extent(),offset_x,offset_y),
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)
: renderer_common(width, height, scale_factor,
vars,
CoordTransform(req.width(),req.height(),req.extent(),offset_x,offset_y),
std::make_shared<label_collision_detector4>(
box2d<double>(-req.buffer_size(), -req.buffer_size(),
@ -70,6 +77,7 @@ renderer_common::renderer_common(renderer_common const &other)
: width_(other.width_),
height_(other.height_),
scale_factor_(other.scale_factor_),
vars_(other.vars_),
shared_font_engine_(other.shared_font_engine_),
font_engine_(*shared_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_list &thunks,
mapnik::feature_impl &feature,
feature_impl &feature,
attributes const& vars,
proj_transform const &prj_trans,
renderer_common &common,
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)
{}
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(
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_;
text_symbolizer_helper helper(
sym, feature_, prj_trans_,
sym, feature_, vars_, prj_trans_,
common_.width_, common_.height_,
common_.scale_factor_,
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_;
text_symbolizer_helper helper(
sym, feature_, prj_trans_,
sym, feature_, vars_, prj_trans_,
common_.width_, common_.height_,
common_.scale_factor_,
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
{
double opacity = get<double>(sym, keys::opacity, feature_, 1.0);
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature_, src_over);
halo_rasterizer_enum halo_rasterizer = get<halo_rasterizer_enum>(sym, keys::halo_rasterizer, HALO_RASTERIZER_FULL);
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_, common_.vars_, src_over);
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();
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),
generator_(output_iterator),
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>
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),
output_iterator_(output_iterator),
generator_(output_iterator),
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>

View file

@ -29,7 +29,9 @@
namespace mapnik {
// 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)
{
if (trans_expr)
@ -38,7 +40,7 @@ void evaluate_transform(agg::trans_affine& tr, feature_impl const& feature,
MAPNIK_LOG_DEBUG(transform) << "transform: evaluate "
<< transform_processor_type::to_string(*trans_expr);
#endif
transform_processor_type::evaluate(tr, feature, *trans_expr, scale_factor);
transform_processor_type::evaluate(tr, feature, vars, *trans_expr, scale_factor);
}
}
// 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{ "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{ "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)

View file

@ -32,10 +32,8 @@
#include <mapnik/xml_node.hpp>
//boost
#include <boost/property_tree/ptree.hpp>
namespace mapnik {
namespace formatting {
@ -82,31 +80,30 @@ expression_ptr expression_format::get_expression(xml_node const& xml, std::strin
return expression_ptr();
}
void expression_format::apply(char_properties_ptr p, feature_impl const& feature, text_layout &output) const
void expression_format::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);
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 =
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 =
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 =
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 =
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 =
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(
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(
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 =
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_) {
child_->apply(new_properties, feature, output);
child_->apply(new_properties, feature, vars, output);
} else {
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);
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 (child_) {
child_->apply(new_properties, feature, output);
child_->apply(new_properties, feature, vars, output);
} else {
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;
}
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());
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
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
if (child_) {
child_->apply(p, feature, *child_layout);
child_->apply(p, feature, vars, *child_layout);
} else {
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_)
{
node->apply(p, feature, output);
node->apply(p, feature, vars, output);
}
}

View file

@ -28,13 +28,9 @@
#include <mapnik/xml_node.hpp>
#include <mapnik/text/layout.hpp>
//boost
// boost
#include <boost/property_tree/ptree.hpp>
namespace mapnik
{
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>());
}
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)
{
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_);
}
void text_layout::init_orientation(feature_impl const& feature)
void text_layout::init_orientation(feature_impl const& feature, attributes const& attr)
{
if (properties_->orientation)
{
// 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(
boost::apply_visitor(
evaluator,

View file

@ -41,12 +41,14 @@ namespace mapnik
{
placement_finder::placement_finder(feature_impl const& feature,
attributes const& attr,
DetectorType &detector,
box2d<double> const& extent,
text_placement_info_ptr placement_info,
face_manager_freetype & font_manager,
double scale_factor)
: feature_(feature),
attr_(attr),
detector_(detector),
extent_(extent),
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);
layout->init_orientation(feature_);
info_->properties.process(*layout, feature_);
layout->init_orientation(feature_, attr_);
info_->properties.process(*layout, feature_, attr_);
layouts_.clear();
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)
{
//Only subtract half the line height here and half at the end because text is automatically
//centered on the line
// Only subtract half the line height here and half at the end because text is automatically
// centered on the line
offset -= sign * line.height()/2;
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;
@ -291,7 +293,7 @@ bool placement_finder::single_line_placement(vertex_cache &pp, text_upright_e or
}
current_cluster = glyph.char_index;
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)));
rot.init(angle);
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;
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();
pos.y = -pos.y - char_height/2.0*rot.cos;
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));
glyphs->push_back(glyph, pos, rot);
}
//See comment above
// See comment above
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)
{
//Try again with oposite orientation
// Try again with opposite orientation
begin.restore();
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)
{
return false;

View file

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

View file

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