Merge commit 'e2a76e09b3e3614174d24aa43165151f599c9d8e' into harfbuzz

Conflicts:
	src/agg/process_text_symbolizer.cpp
	src/cairo_renderer.cpp
This commit is contained in:
Hermann Kraus 2013-03-16 12:38:22 +01:00
commit 55d8492b77
14 changed files with 507 additions and 347 deletions

View file

@ -25,6 +25,7 @@
// mapnik
#include <mapnik/raster_symbolizer.hpp>
#include <mapnik/raster_colorizer.hpp>
#include <mapnik/image_scaling.hpp>
using mapnik::raster_symbolizer;

View file

@ -37,8 +37,8 @@
#include <mapnik/expression_evaluator.hpp>
#include <mapnik/utils.hpp>
#include <mapnik/scale_denominator.hpp>
#include <mapnik/agg_renderer.hpp>
#include <mapnik/grid/grid_renderer.hpp>
#include <mapnik/projection.hpp>
#include <mapnik/proj_transform.hpp>
// boost
#include <boost/foreach.hpp>
@ -47,13 +47,6 @@
// stl
#include <vector>
#if defined(HAVE_CAIRO)
#include <mapnik/cairo_renderer.hpp>
#endif
#if defined(SVG_RENDERER)
#include <mapnik/svg/output/svg_renderer.hpp>
#endif
#if defined(RENDERING_STATS)
#include <mapnik/timer.hpp>

View file

@ -24,150 +24,34 @@
#define MAPNIK_RASTER_SYMBOLIZER_HPP
// mapnik
#include <mapnik/config.hpp>
#include <mapnik/debug.hpp>
#include <mapnik/raster_colorizer.hpp>
#include <mapnik/symbolizer.hpp>
#include <mapnik/image_util.hpp>
#include <mapnik/image_compositing.hpp>
#include <mapnik/raster_colorizer.hpp>
#include <mapnik/image_scaling.hpp>
// boost
#include <boost/algorithm/string.hpp>
#include <boost/shared_ptr.hpp>
namespace mapnik
{
struct MAPNIK_DECL raster_symbolizer : public symbolizer_base
{
raster_symbolizer();
raster_symbolizer(raster_symbolizer const& rhs);
raster_symbolizer()
: symbolizer_base(),
mode_("normal"),
scaling_(SCALING_NEAR),
opacity_(1.0),
colorizer_(),
filter_factor_(-1),
mesh_size_(16) {}
raster_symbolizer(const raster_symbolizer &rhs)
: symbolizer_base(rhs),
mode_(rhs.mode_),
scaling_(rhs.scaling_),
opacity_(rhs.opacity_),
colorizer_(rhs.colorizer_),
filter_factor_(rhs.filter_factor_),
mesh_size_(rhs.mesh_size_) {}
std::string const& get_mode() const
{
MAPNIK_LOG_ERROR(raster_symbolizer) << "getting 'mode' is deprecated and will be removed in Mapnik 3.x, use 'comp-op' with Mapnik >= 2.1.x";
return mode_;
}
void set_mode(std::string const& mode)
{
MAPNIK_LOG_ERROR(raster_symbolizer) << "setting 'mode' is deprecated and will be removed in Mapnik 3.x, use 'comp-op' with Mapnik >= 2.1.x";
mode_ = mode;
if (mode == "normal")
{
MAPNIK_LOG_ERROR(raster_symbolizer) << "converting 'mode=normal' to 'comp-op:src_over'";
this->set_comp_op(src_over);
}
else
{
std::string mode2 = boost::algorithm::replace_last_copy(mode,"2","");
boost::optional<composite_mode_e> comp_op = comp_op_from_string(mode2);
if (comp_op)
{
MAPNIK_LOG_ERROR(raster_symbolizer) << "converting 'mode:" << mode << "' to 'comp-op:" + *comp_op_to_string(*comp_op) + "'";
this->set_comp_op(*comp_op);
}
else
{
MAPNIK_LOG_ERROR(raster_symbolizer) << "could not convert mode '" << mode << "' into comp-op, defaulting to 'comp-op:src-over'";
}
}
}
scaling_method_e get_scaling_method() const
{
return scaling_;
}
void set_scaling_method(scaling_method_e scaling)
{
scaling_ = scaling;
}
void set_opacity(float opacity)
{
opacity_ = opacity;
}
float get_opacity() const
{
return opacity_;
}
raster_colorizer_ptr get_colorizer() const
{
return colorizer_;
}
void set_colorizer(raster_colorizer_ptr const& colorizer)
{
colorizer_ = colorizer;
}
double get_filter_factor() const
{
return filter_factor_;
}
void set_filter_factor(double filter_factor)
{
filter_factor_=filter_factor;
}
double calculate_filter_factor() const
{
if (filter_factor_ > 0)
{
// respect explicitly specified values
return filter_factor_;
} else {
double ff = 1.0;
switch(scaling_)
{
case SCALING_NEAR:
ff = 1.0;
break;
// TODO potentially some of these algorithms would use filter_factor >2.0.
// Contributions welcome from someone who knows more about them.
case SCALING_BILINEAR:
case SCALING_BILINEAR8:
case SCALING_BICUBIC:
case SCALING_SPLINE16:
case SCALING_SPLINE36:
case SCALING_HANNING:
case SCALING_HAMMING:
case SCALING_HERMITE:
case SCALING_KAISER:
case SCALING_QUADRIC:
case SCALING_CATROM:
case SCALING_GAUSSIAN:
case SCALING_BESSEL:
case SCALING_MITCHELL:
case SCALING_SINC:
case SCALING_LANCZOS:
case SCALING_BLACKMAN:
ff = 2.0;
break;
}
return ff;
}
}
unsigned get_mesh_size() const
{
return mesh_size_;
}
void set_mesh_size(unsigned mesh_size)
{
mesh_size_=mesh_size;
}
std::string const& get_mode() const;
void set_mode(std::string const& mode);
scaling_method_e get_scaling_method() const;
void set_scaling_method(scaling_method_e scaling);
void set_opacity(float opacity);
float get_opacity() const;
raster_colorizer_ptr get_colorizer() const;
void set_colorizer(raster_colorizer_ptr const& colorizer);
double get_filter_factor() const;
void set_filter_factor(double filter_factor);
double calculate_filter_factor() const;
unsigned get_mesh_size() const;
void set_mesh_size(unsigned mesh_size);
private:
std::string mode_;

View file

@ -141,213 +141,35 @@ private:
bool else_filter_;
bool also_filter_;
struct deepcopy_symbolizer : public boost::static_visitor<>
{
void operator () (raster_symbolizer & sym) const
{
raster_colorizer_ptr old_colorizer = sym.get_colorizer();
raster_colorizer_ptr new_colorizer = raster_colorizer_ptr();
new_colorizer->set_stops(old_colorizer->get_stops());
new_colorizer->set_default_mode(old_colorizer->get_default_mode());
new_colorizer->set_default_color(old_colorizer->get_default_color());
new_colorizer->set_epsilon(old_colorizer->get_epsilon());
sym.set_colorizer(new_colorizer);
}
void operator () (text_symbolizer & sym) const
{
copy_text_ptr(sym);
}
void operator () (shield_symbolizer & sym) const
{
copy_text_ptr(sym);
}
void operator () (building_symbolizer & sym) const
{
copy_height_ptr(sym);
}
template <typename T> void operator () (T &sym) const
{
boost::ignore_unused_variable_warning(sym);
}
private:
template <class T>
void copy_text_ptr(T & sym) const
{
boost::ignore_unused_variable_warning(sym);
MAPNIK_LOG_WARN(rule) << "rule: deep copying TextSymbolizers is broken!";
}
template <class T>
void copy_height_ptr(T & sym) const
{
std::string height_expr = to_expression_string(*sym.height());
sym.set_height(parse_expression(height_expr,"utf8"));
}
};
public:
rule()
: name_(),
min_scale_(0),
max_scale_(std::numeric_limits<double>::infinity()),
syms_(),
filter_(boost::make_shared<mapnik::expr_node>(true)),
else_filter_(false),
also_filter_(false) {}
rule();
rule(std::string const& name,
double min_scale_denominator=0,
double max_scale_denominator=std::numeric_limits<double>::infinity())
: name_(name),
min_scale_(min_scale_denominator),
max_scale_(max_scale_denominator),
syms_(),
filter_(boost::make_shared<mapnik::expr_node>(true)),
else_filter_(false),
also_filter_(false) {}
double min_scale_denominator = 0,
double max_scale_denominator = std::numeric_limits<double>::infinity());
rule(const rule& rhs, bool deep_copy = false);
rule(const rule& rhs, bool deep_copy = false)
: name_(rhs.name_),
min_scale_(rhs.min_scale_),
max_scale_(rhs.max_scale_),
syms_(rhs.syms_),
filter_(rhs.filter_),
else_filter_(rhs.else_filter_),
also_filter_(rhs.also_filter_)
{
if (deep_copy) {
std::string expr = to_expression_string(*filter_);
filter_ = parse_expression(expr,"utf8");
symbolizers::const_iterator it = syms_.begin();
symbolizers::const_iterator end = syms_.end();
for(; it != end; ++it)
{
boost::apply_visitor(deepcopy_symbolizer(),*it);
}
}
}
rule& operator=(rule const& rhs)
{
rule tmp(rhs);
swap(tmp);
return *this;
}
bool operator==(rule const& other)
{
return (this == &other);
}
void set_max_scale(double scale)
{
max_scale_=scale;
}
double get_max_scale() const
{
return max_scale_;
}
void set_min_scale(double scale)
{
min_scale_=scale;
}
double get_min_scale() const
{
return min_scale_;
}
void set_name(std::string const& name)
{
name_=name;
}
std::string const& get_name() const
{
return name_;
}
void append(const symbolizer& sym)
{
syms_.push_back(sym);
}
void remove_at(size_t index)
{
if (index < syms_.size())
{
syms_.erase(syms_.begin()+index);
}
}
const symbolizers& get_symbolizers() const
{
return syms_;
}
symbolizers::const_iterator begin() const
{
return syms_.begin();
}
symbolizers::const_iterator end() const
{
return syms_.end();
}
symbolizers::iterator begin()
{
return syms_.begin();
}
symbolizers::iterator end()
{
return syms_.end();
}
void set_filter(const expression_ptr& filter)
{
filter_=filter;
}
expression_ptr const& get_filter() const
{
return filter_;
}
void set_else(bool else_filter)
{
else_filter_=else_filter;
}
bool has_else_filter() const
{
return else_filter_;
}
void set_also(bool also_filter)
{
also_filter_=also_filter;
}
bool has_also_filter() const
{
return also_filter_;
}
bool active(double scale) const
{
return ( scale >= min_scale_ - 1e-6 && scale < max_scale_ + 1e-6);
}
rule& operator=(rule const& rhs);
bool operator==(rule const& other);
void set_max_scale(double scale);
double get_max_scale() const;
void set_min_scale(double scale);
double get_min_scale() const;
void set_name(std::string const& name);
std::string const& get_name() const;
void append(symbolizer const& sym);
void remove_at(size_t index);
const symbolizers& get_symbolizers() const;
symbolizers::const_iterator begin() const;
symbolizers::const_iterator end() const;
symbolizers::iterator begin();
symbolizers::iterator end();
void set_filter(expression_ptr const& filter);
expression_ptr const& get_filter() const;
void set_else(bool else_filter);
bool has_else_filter() const;
void set_also(bool also_filter);
bool has_also_filter() const;
bool active(double scale) const;
private:

View file

@ -25,6 +25,8 @@
#include <mapnik/image_scaling.hpp>
#include <mapnik/image_compositing.hpp>
#include <mapnik/graphics.hpp>
#include <mapnik/raster_symbolizer.hpp>
#include <mapnik/raster_colorizer.hpp>
#include <mapnik/agg_rasterizer.hpp>
#include <mapnik/image_data.hpp>
#include <mapnik/image_util.hpp>

View file

@ -25,6 +25,7 @@
#include <mapnik/text/symbolizer_helpers.hpp>
#include <mapnik/text/renderer.hpp>
#include <boost/foreach.hpp>
#include <mapnik/graphics.hpp>
namespace mapnik {

View file

@ -141,6 +141,7 @@ source = Split(
point_symbolizer.cpp
polygon_pattern_symbolizer.cpp
polygon_symbolizer.cpp
rule.cpp
save_map.cpp
shield_symbolizer.cpp
text_symbolizer.cpp
@ -157,6 +158,7 @@ source = Split(
unicode.cpp
markers_symbolizer.cpp
raster_colorizer.cpp
raster_symbolizer.cpp
wkt/wkt_factory.cpp
wkt/wkt_generator.cpp
mapped_memory_cache.cpp

View file

@ -37,6 +37,7 @@
#include <mapnik/svg/svg_path_attributes.hpp>
#include <mapnik/segment.hpp>
#include <mapnik/text/symbolizer_helpers.hpp>
#include <mapnik/raster_colorizer.hpp>
#include <mapnik/expression_evaluator.hpp>
#include <mapnik/warp.hpp>
#include <mapnik/config.hpp>

View file

@ -22,6 +22,20 @@
// mapnik
#include <mapnik/feature_style_processor_impl.hpp>
#include <mapnik/agg_renderer.hpp>
#include <mapnik/graphics.hpp>
#include <mapnik/grid/grid_renderer.hpp>
#include <mapnik/grid/grid.hpp>
#if defined(HAVE_CAIRO)
#include <cairomm/context.h>
#include <cairomm/surface.h>
#include <mapnik/cairo_renderer.hpp>
#endif
#if defined(SVG_RENDERER)
#include <mapnik/svg/output/svg_renderer.hpp>
#endif
namespace mapnik
{

View file

@ -99,6 +99,21 @@ boost::optional<std::string> comp_op_to_string(composite_mode_e comp_op)
return mode;
}
/*
Note: the difference between agg::pixfmt_rgba32 and agg:pixfmt_rgba32_pre is subtle.
From http://www.antigrain.com/news/release_notes/v22.agdoc.html:
Format agg::pixfmt_rgba32 is the main and the fastest pixel format and it's supposed to be used in most cases. But it always uses plain colors as input and produces pre-multiplied result on the canvas. It has even less number of calculations than agg::pixfmt_rgba32_pre. Format agg::pixfmt_rgba32_plain is slow because of division operations. APIs allowing for alpha-blending require premultiplied colors. Besides, if you display RGBA with RGB API (that is, without alpha, like WinAPI BitBlt), the colors still must be premultiplied. Note that the formulas in agg::pixfmt_rgba32 and agg::pixfmt_rgb24 are exactly the same! So, premultiplied colors are more natural and agg::pixfmt_rgba32_plain is rather useless.
Format agg::pixfmt_rgba32_pre is a bit slower than agg::pixfmt_rgba32 because of additional "cover" values, i.e. secondary alphas, that are to be mixed with the source premultiplied color. That spoils the beauty of the premultiplied colors idea. But the "cover" values are important because there can be other color spaces and color types that don't have any "alpha" at all, or the alpha is incompatible with integral types. So, the "cover" is a secondary, uniform alpha in range of 0255, used specifically for anti-aliasing purposes.
One needs to consider this issue when transforming images. Actually, all RGBA images are supposed to be in the premultiplied color space and the result of filtering is also premultiplied. Since the resulting colors of the filtered images are the source for the renderers, one should use the premultiplied renderers, that is, agg::pixfmt_rgba32_pre, or the new one, agg::pixfmt_rgb24_pre. But it's important only if images are translucent, that is, have actual alpha channel.
For example, if you generate some pattern with AGG (premultiplied) and would like to use it for filling, you'll need to use agg::pixfmt_rgba32_pre. If you use agg::span_image_filter_rgb24_gamma_bilinear (that is, RGB for input) and draw it on the RGBA canvas, you still need to use agg::pixfmt_rgba32_pre as the destination canvas. The only thing you need is to premultiply the background color used out of bounds.
*/
template <typename T1, typename T2>
void composite(T1 & dst, T2 & src, composite_mode_e mode,
float opacity,

View file

@ -263,6 +263,9 @@ void scale_image_agg(Image & target,
double filter_radius,
double ratio)
{
// TODO - should all types here be *_pre ?
// "the image filters should work namely in the premultiplied color space"
// http://old.nabble.com/Re:--AGG--Basic-image-transformations-p1110665.html
typedef agg::pixfmt_rgba32 pixfmt;
typedef agg::pixfmt_rgba32_pre pixfmt_pre;
typedef agg::renderer_base<pixfmt_pre> renderer_base;

182
src/raster_symbolizer.cpp Normal file
View file

@ -0,0 +1,182 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2012 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
// mapnik
#include <mapnik/raster_symbolizer.hpp>
// mapnik
#include <mapnik/config.hpp>
#include <mapnik/debug.hpp>
#include <mapnik/raster_colorizer.hpp>
#include <mapnik/symbolizer.hpp>
#include <mapnik/image_util.hpp>
#include <mapnik/image_compositing.hpp>
#include <mapnik/image_scaling.hpp>
// boost
#include <boost/algorithm/string.hpp>
namespace mapnik
{
raster_symbolizer::raster_symbolizer()
: symbolizer_base(),
mode_("normal"),
scaling_(SCALING_NEAR),
opacity_(1.0),
colorizer_(),
filter_factor_(-1),
mesh_size_(16) {}
raster_symbolizer::raster_symbolizer(raster_symbolizer const& rhs)
: symbolizer_base(rhs),
mode_(rhs.mode_),
scaling_(rhs.scaling_),
opacity_(rhs.opacity_),
colorizer_(rhs.colorizer_),
filter_factor_(rhs.filter_factor_),
mesh_size_(rhs.mesh_size_) {}
std::string const& raster_symbolizer::get_mode() const
{
MAPNIK_LOG_ERROR(raster_symbolizer) << "getting 'mode' is deprecated and will be removed in Mapnik 3.x, use 'comp-op' with Mapnik >= 2.1.x";
return mode_;
}
void raster_symbolizer::set_mode(std::string const& mode)
{
MAPNIK_LOG_ERROR(raster_symbolizer) << "setting 'mode' is deprecated and will be removed in Mapnik 3.x, use 'comp-op' with Mapnik >= 2.1.x";
mode_ = mode;
if (mode == "normal")
{
MAPNIK_LOG_ERROR(raster_symbolizer) << "converting 'mode=normal' to 'comp-op:src_over'";
this->set_comp_op(src_over);
}
else
{
std::string mode2 = boost::algorithm::replace_last_copy(mode,"2","");
boost::optional<composite_mode_e> comp_op = comp_op_from_string(mode2);
if (comp_op)
{
MAPNIK_LOG_ERROR(raster_symbolizer) << "converting 'mode:" << mode << "' to 'comp-op:" + *comp_op_to_string(*comp_op) + "'";
this->set_comp_op(*comp_op);
}
else
{
MAPNIK_LOG_ERROR(raster_symbolizer) << "could not convert mode '" << mode << "' into comp-op, defaulting to 'comp-op:src-over'";
}
}
}
scaling_method_e raster_symbolizer::get_scaling_method() const
{
return scaling_;
}
void raster_symbolizer::set_scaling_method(scaling_method_e scaling)
{
scaling_ = scaling;
}
void raster_symbolizer::set_opacity(float opacity)
{
opacity_ = opacity;
}
float raster_symbolizer::get_opacity() const
{
return opacity_;
}
raster_colorizer_ptr raster_symbolizer::get_colorizer() const
{
return colorizer_;
}
void raster_symbolizer::set_colorizer(raster_colorizer_ptr const& colorizer)
{
colorizer_ = colorizer;
}
double raster_symbolizer::get_filter_factor() const
{
return filter_factor_;
}
void raster_symbolizer::set_filter_factor(double filter_factor)
{
filter_factor_=filter_factor;
}
double raster_symbolizer::calculate_filter_factor() const
{
if (filter_factor_ > 0)
{
// respect explicitly specified values
return filter_factor_;
} else {
double ff = 1.0;
switch(scaling_)
{
case SCALING_NEAR:
ff = 1.0;
break;
// TODO potentially some of these algorithms would use filter_factor >2.0.
// Contributions welcome from someone who knows more about them.
case SCALING_BILINEAR:
case SCALING_BILINEAR8:
case SCALING_BICUBIC:
case SCALING_SPLINE16:
case SCALING_SPLINE36:
case SCALING_HANNING:
case SCALING_HAMMING:
case SCALING_HERMITE:
case SCALING_KAISER:
case SCALING_QUADRIC:
case SCALING_CATROM:
case SCALING_GAUSSIAN:
case SCALING_BESSEL:
case SCALING_MITCHELL:
case SCALING_SINC:
case SCALING_LANCZOS:
case SCALING_BLACKMAN:
ff = 2.0;
break;
}
return ff;
}
}
unsigned raster_symbolizer::get_mesh_size() const
{
return mesh_size_;
}
void raster_symbolizer::set_mesh_size(unsigned mesh_size)
{
mesh_size_=mesh_size;
}
}

239
src/rule.cpp Normal file
View file

@ -0,0 +1,239 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2011 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
// mapnik
#include <mapnik/rule.hpp>
#include <mapnik/raster_colorizer.hpp>
namespace {
struct deepcopy_symbolizer : public boost::static_visitor<>
{
void operator () (mapnik::raster_symbolizer & sym) const
{
mapnik::raster_colorizer_ptr old_colorizer = sym.get_colorizer();
mapnik::raster_colorizer_ptr new_colorizer = mapnik::raster_colorizer_ptr();
new_colorizer->set_stops(old_colorizer->get_stops());
new_colorizer->set_default_mode(old_colorizer->get_default_mode());
new_colorizer->set_default_color(old_colorizer->get_default_color());
new_colorizer->set_epsilon(old_colorizer->get_epsilon());
sym.set_colorizer(new_colorizer);
}
void operator () (mapnik::text_symbolizer & sym) const
{
copy_text_ptr(sym);
}
void operator () (mapnik::shield_symbolizer & sym) const
{
copy_text_ptr(sym);
}
void operator () (mapnik::building_symbolizer & sym) const
{
copy_height_ptr(sym);
}
template <typename T> void operator () (T &sym) const
{
boost::ignore_unused_variable_warning(sym);
}
template <class T>
void copy_text_ptr(T & sym) const
{
boost::ignore_unused_variable_warning(sym);
MAPNIK_LOG_WARN(rule) << "rule: deep copying TextSymbolizers is broken!";
}
template <class T>
void copy_height_ptr(T & sym) const
{
std::string height_expr = mapnik::to_expression_string(*sym.height());
sym.set_height(mapnik::parse_expression(height_expr,"utf8"));
}
};
}
namespace mapnik
{
rule::rule()
: name_(),
min_scale_(0),
max_scale_(std::numeric_limits<double>::infinity()),
syms_(),
filter_(boost::make_shared<mapnik::expr_node>(true)),
else_filter_(false),
also_filter_(false) {}
rule::rule(std::string const& name,
double min_scale_denominator,
double max_scale_denominator)
: name_(name),
min_scale_(min_scale_denominator),
max_scale_(max_scale_denominator),
syms_(),
filter_(boost::make_shared<mapnik::expr_node>(true)),
else_filter_(false),
also_filter_(false) {}
rule::rule(const rule& rhs, bool deep_copy)
: name_(rhs.name_),
min_scale_(rhs.min_scale_),
max_scale_(rhs.max_scale_),
syms_(rhs.syms_),
filter_(rhs.filter_),
else_filter_(rhs.else_filter_),
also_filter_(rhs.also_filter_)
{
if (deep_copy) {
std::string expr = to_expression_string(*filter_);
filter_ = parse_expression(expr,"utf8");
symbolizers::const_iterator it = syms_.begin();
symbolizers::const_iterator end = syms_.end();
for(; it != end; ++it)
{
boost::apply_visitor(deepcopy_symbolizer(),*it);
}
}
}
rule& rule::operator=(rule const& rhs)
{
rule tmp(rhs);
swap(tmp);
return *this;
}
bool rule::operator==(rule const& other)
{
return (this == &other);
}
void rule::set_max_scale(double scale)
{
max_scale_=scale;
}
double rule::get_max_scale() const
{
return max_scale_;
}
void rule::set_min_scale(double scale)
{
min_scale_=scale;
}
double rule::get_min_scale() const
{
return min_scale_;
}
void rule::set_name(std::string const& name)
{
name_=name;
}
std::string const& rule::get_name() const
{
return name_;
}
void rule::append(symbolizer const& sym)
{
syms_.push_back(sym);
}
void rule::remove_at(size_t index)
{
if (index < syms_.size())
{
syms_.erase(syms_.begin()+index);
}
}
rule::symbolizers const& rule::get_symbolizers() const
{
return syms_;
}
rule::symbolizers::const_iterator rule::begin() const
{
return syms_.begin();
}
rule::symbolizers::const_iterator rule::end() const
{
return syms_.end();
}
rule::symbolizers::iterator rule::begin()
{
return syms_.begin();
}
rule::symbolizers::iterator rule::end()
{
return syms_.end();
}
void rule::set_filter(expression_ptr const& filter)
{
filter_=filter;
}
expression_ptr const& rule::get_filter() const
{
return filter_;
}
void rule::set_else(bool else_filter)
{
else_filter_=else_filter;
}
bool rule::has_else_filter() const
{
return else_filter_;
}
void rule::set_also(bool also_filter)
{
also_filter_=also_filter;
}
bool rule::has_also_filter() const
{
return also_filter_;
}
bool rule::active(double scale) const
{
return ( scale >= min_scale_ - 1e-6 && scale < max_scale_ + 1e-6);
}
}

View file

@ -30,6 +30,7 @@
#include <mapnik/feature_type_style.hpp>
#include <mapnik/text/text_properties.hpp>
#include <mapnik/config_error.hpp>
#include <mapnik/raster_colorizer.hpp>
//boost
#include <boost/lexical_cast.hpp>