Updated grid renderer for expr-v2 branch.

All the grid visual tests pass.

One small issue is that in the grid line pattern symbolizer it
constructs a 'fake' line symbolizer to re-use code (as the grid
renderer cares nothing for patterns), but doesn't pass the
offset parameter to it. The tests currently require this
behaviour, but they should probably be changed as it seems
incorrect.
This commit is contained in:
Matt Amos 2013-12-02 13:46:52 +00:00
parent c57d88edb1
commit d64b86dcdf
12 changed files with 171 additions and 137 deletions

View file

@ -24,7 +24,7 @@
#define MAPNIK_GRID_MARKER_HELPERS_HPP #define MAPNIK_GRID_MARKER_HELPERS_HPP
// mapnik // mapnik
#include <mapnik/markers_symbolizer.hpp> #include <mapnik/symbolizer.hpp>
#include <mapnik/markers_placement.hpp> #include <mapnik/markers_placement.hpp>
#include <mapnik/geometry.hpp> #include <mapnik/geometry.hpp>
#include <mapnik/geom_util.hpp> #include <mapnik/geom_util.hpp>
@ -76,7 +76,12 @@ struct raster_markers_rasterizer_dispatch_grid
template <typename T> template <typename T>
void add_path(T & path) void add_path(T & path)
{ {
marker_placement_e placement_method = sym_.get_marker_placement(); 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);
box2d<double> bbox_(0,0, src_.width(),src_.height()); box2d<double> bbox_(0,0, src_.width(),src_.height());
if (placement_method != MARKER_LINE_PLACEMENT || if (placement_method != MARKER_LINE_PLACEMENT ||
path.type() == geometry_type::types::Point) path.type() == geometry_type::types::Point)
@ -101,11 +106,11 @@ struct raster_markers_rasterizer_dispatch_grid
agg::trans_affine matrix = marker_trans_; agg::trans_affine matrix = marker_trans_;
matrix.translate(x,y); matrix.translate(x,y);
box2d<double> transformed_bbox = bbox_ * matrix; box2d<double> transformed_bbox = bbox_ * matrix;
if (sym_.get_allow_overlap() || if (allow_overlap ||
detector_.has_placement(transformed_bbox)) detector_.has_placement(transformed_bbox))
{ {
render_raster_marker(matrix); render_raster_marker(matrix);
if (!sym_.get_ignore_placement()) if (!ignore_placement)
{ {
detector_.insert(transformed_bbox); detector_.insert(transformed_bbox);
} }
@ -119,11 +124,11 @@ struct raster_markers_rasterizer_dispatch_grid
else else
{ {
markers_placement<T, label_collision_detector4> placement(path, bbox_, marker_trans_, detector_, markers_placement<T, label_collision_detector4> placement(path, bbox_, marker_trans_, detector_,
sym_.get_spacing() * scale_factor_, spacing * scale_factor_,
sym_.get_max_error(), max_error,
sym_.get_allow_overlap()); allow_overlap);
double x, y, angle; double x, y, angle;
while (placement.get_point(x, y, angle, sym_.get_ignore_placement())) while (placement.get_point(x, y, angle, ignore_placement))
{ {
agg::trans_affine matrix = marker_trans_; agg::trans_affine matrix = marker_trans_;
matrix.rotate(angle); matrix.rotate(angle);
@ -214,7 +219,13 @@ struct vector_markers_rasterizer_dispatch_grid
template <typename T> template <typename T>
void add_path(T & path) void add_path(T & path)
{ {
marker_placement_e placement_method = sym_.get_marker_placement(); 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);
if (placement_method != MARKER_LINE_PLACEMENT || if (placement_method != MARKER_LINE_PLACEMENT ||
path.type() == geometry_type::types::Point) path.type() == geometry_type::types::Point)
{ {
@ -238,11 +249,11 @@ struct vector_markers_rasterizer_dispatch_grid
agg::trans_affine matrix = marker_trans_; agg::trans_affine matrix = marker_trans_;
matrix.translate(x,y); matrix.translate(x,y);
box2d<double> transformed_bbox = bbox_ * matrix; box2d<double> transformed_bbox = bbox_ * matrix;
if (sym_.get_allow_overlap() || if (allow_overlap ||
detector_.has_placement(transformed_bbox)) detector_.has_placement(transformed_bbox))
{ {
svg_renderer_.render_id(ras_, sl_, renb_, feature_.id(), matrix, sym_.get_opacity(), bbox_); svg_renderer_.render_id(ras_, sl_, renb_, feature_.id(), matrix, opacity, bbox_);
if (!sym_.get_ignore_placement()) if (!ignore_placement)
{ {
detector_.insert(transformed_bbox); detector_.insert(transformed_bbox);
} }
@ -256,16 +267,16 @@ struct vector_markers_rasterizer_dispatch_grid
else else
{ {
markers_placement<T, Detector> placement(path, bbox_, marker_trans_, detector_, markers_placement<T, Detector> placement(path, bbox_, marker_trans_, detector_,
sym_.get_spacing() * scale_factor_, spacing * scale_factor_,
sym_.get_max_error(), max_error,
sym_.get_allow_overlap()); allow_overlap);
double x, y, angle; double x, y, angle;
while (placement.get_point(x, y, angle, sym_.get_ignore_placement())) while (placement.get_point(x, y, angle, ignore_placement))
{ {
agg::trans_affine matrix = marker_trans_; agg::trans_affine matrix = marker_trans_;
matrix.rotate(angle); matrix.rotate(angle);
matrix.translate(x, y); matrix.translate(x, y);
svg_renderer_.render_id(ras_, sl_, renb_, feature_.id(), matrix, sym_.get_opacity(), bbox_); svg_renderer_.render_id(ras_, sl_, renb_, feature_.id(), matrix, opacity, bbox_);
if (!placed_) if (!placed_)
{ {
pixmap_.add_feature(feature_); pixmap_.add_feature(feature_);

View file

@ -478,8 +478,6 @@ void cairo_context::add_text(glyph_positions_ptr path,
if (glyph.format) if (glyph.format)
{ {
format = glyph.format; format = glyph.format;
// Settings have changed.
halo_radius = format->halo_radius * scale_factor;
} }
face_set_ptr faces = font_manager.get_face_set(format->face_name, format->fontset); face_set_ptr faces = font_manager.get_face_set(format->face_name, format->fontset);

View file

@ -200,7 +200,8 @@ void grid_renderer<T>::render_marker(mapnik::feature_impl & feature, unsigned in
data, data,
SCALING_NEAR, SCALING_NEAR,
ratio, ratio,
ratio); ratio,
0.0, 0.0, 1.0); // TODO: is 1.0 a valid default here, and do we even care in grid_renderer what the image looks like?
pixmap_.set_rectangle(feature.id(), target, pixmap_.set_rectangle(feature.id(), target,
boost::math::iround(pos.x - cx), boost::math::iround(pos.x - cx),
boost::math::iround(pos.y - cy)); boost::math::iround(pos.y - cy));

View file

@ -28,7 +28,6 @@
#include <mapnik/grid/grid.hpp> #include <mapnik/grid/grid.hpp>
#include <mapnik/segment.hpp> #include <mapnik/segment.hpp>
#include <mapnik/expression_evaluator.hpp> #include <mapnik/expression_evaluator.hpp>
#include <mapnik/building_symbolizer.hpp>
#include <mapnik/expression.hpp> #include <mapnik/expression.hpp>
// boost // boost
@ -65,14 +64,7 @@ void grid_renderer<T>::process(building_symbolizer const& sym,
ras_ptr->reset(); ras_ptr->reset();
double height = 0.0; double height = get<value_double>(sym, keys::height,feature, 0.0);
expression_ptr height_expr = sym.height();
if (height_expr)
{
value_type result = boost::apply_visitor(evaluate<feature_impl,value_type>(feature), *height_expr);
height = result.to_double() * scale_factor_;
}
for (std::size_t i=0;i<feature.num_geometries();++i) for (std::size_t i=0;i<feature.num_geometries();++i)
{ {
geometry_type & geom = feature.get_geometry(i); geometry_type & geom = feature.get_geometry(i);

View file

@ -26,7 +26,6 @@
#include <mapnik/grid/grid_renderer.hpp> #include <mapnik/grid/grid_renderer.hpp>
#include <mapnik/grid/grid_renderer_base.hpp> #include <mapnik/grid/grid_renderer_base.hpp>
#include <mapnik/grid/grid.hpp> #include <mapnik/grid/grid.hpp>
#include <mapnik/line_pattern_symbolizer.hpp>
#include <mapnik/marker.hpp> #include <mapnik/marker.hpp>
#include <mapnik/marker_cache.hpp> #include <mapnik/marker_cache.hpp>
#include <mapnik/vertex_converters.hpp> #include <mapnik/vertex_converters.hpp>
@ -49,7 +48,7 @@ void grid_renderer<T>::process(line_pattern_symbolizer const& sym,
mapnik::feature_impl & feature, mapnik::feature_impl & feature,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
std::string filename = path_processor_type::evaluate( *sym.get_filename(), feature); std::string filename = get<std::string>(sym, keys::file, feature);
boost::optional<marker_ptr> mark = marker_cache::instance().find(filename,true); boost::optional<marker_ptr> mark = marker_cache::instance().find(filename,true);
if (!mark) return; if (!mark) return;
@ -63,6 +62,11 @@ void grid_renderer<T>::process(line_pattern_symbolizer const& sym,
boost::optional<image_ptr> pat = (*mark)->get_bitmap_data(); boost::optional<image_ptr> pat = (*mark)->get_bitmap_data();
if (!pat) return; if (!pat) return;
bool clip = get<value_bool>(sym, keys::clip, feature);
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);
typedef coord_transform<CoordTransform,geometry_type> path_type; typedef coord_transform<CoordTransform,geometry_type> path_type;
typedef typename grid_renderer_base_type::pixfmt_type pixfmt_type; typedef typename grid_renderer_base_type::pixfmt_type pixfmt_type;
typedef typename grid_renderer_base_type::pixfmt_type::color_type color_type; typedef typename grid_renderer_base_type::pixfmt_type::color_type color_type;
@ -83,35 +87,42 @@ void grid_renderer<T>::process(line_pattern_symbolizer const& sym,
int stroke_width = (*pat)->width(); int stroke_width = (*pat)->width();
agg::trans_affine tr; agg::trans_affine tr;
evaluate_transform(tr, feature, sym.get_transform()); auto transform = get_optional<transform_type>(sym, keys::geometry_transform);
if (transform) { evaluate_transform(tr, feature, *transform); }
box2d<double> clipping_extent = query_extent_; box2d<double> clipping_extent = query_extent_;
if (sym.clip()) if (clip)
{ {
double padding = (double)(query_extent_.width()/pixmap_.width()); double padding = (double)(query_extent_.width()/pixmap_.width());
double half_stroke = stroke_width/2.0; double half_stroke = stroke_width/2.0;
if (half_stroke > 1) if (half_stroke > 1)
padding *= half_stroke; padding *= half_stroke;
if (std::fabs(sym.offset()) > 0) if (std::fabs(offset) > 0)
padding *= std::fabs(sym.offset()) * 1.2; padding *= std::fabs(offset) * 1.2;
padding *= scale_factor_; padding *= scale_factor_;
clipping_extent.pad(padding); clipping_extent.pad(padding);
} }
// to avoid the complexity of using an agg pattern filter instead // to avoid the complexity of using an agg pattern filter instead
// we create a line_symbolizer in order to fake the pattern // we create a line_symbolizer in order to fake the pattern
stroke str; line_symbolizer line;
str.set_width(stroke_width); put<value_double>(line, keys::stroke_width, value_double(stroke_width));
line_symbolizer line(str); // TODO: really should pass the offset to the fake line too, but
// this wasn't present in the previous version and makes the test
// fail - in this case, probably the test should be updated.
//put<value_double>(line, keys::offset, value_double(offset));
put<value_double>(line, keys::simplify_tolerance, value_double(simplify_tolerance));
put<value_double>(line, keys::smooth, value_double(smooth));
vertex_converter<box2d<double>, grid_rasterizer, line_symbolizer, vertex_converter<box2d<double>, grid_rasterizer, line_symbolizer,
CoordTransform, proj_transform, agg::trans_affine, conv_types> CoordTransform, proj_transform, agg::trans_affine, conv_types>
converter(clipping_extent,*ras_ptr,line,t_,prj_trans,tr,scale_factor_); converter(clipping_extent,*ras_ptr,line,t_,prj_trans,tr,scale_factor_);
if (sym.clip()) converter.set<clip_line_tag>(); // optional clip (default: true) if (clip) converter.set<clip_line_tag>(); // optional clip (default: true)
converter.set<transform_tag>(); // always transform converter.set<transform_tag>(); // always transform
if (std::fabs(sym.offset()) > 0.0) converter.set<offset_transform_tag>(); // parallel offset if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset
converter.set<affine_transform_tag>(); // optional affine transform converter.set<affine_transform_tag>(); // optional affine transform
if (sym.simplify_tolerance() > 0.0) converter.set<simplify_tag>(); // optional simplify converter if (simplify_tolerance > 0.0) converter.set<simplify_tag>(); // optional simplify converter
if (sym.smooth() > 0.0) converter.set<smooth_tag>(); // optional smooth converter if (smooth > 0.0) converter.set<smooth_tag>(); // optional smooth converter
converter.set<stroke_tag>(); //always stroke converter.set<stroke_tag>(); //always stroke
for (geometry_type & geom : feature.paths()) for (geometry_type & geom : feature.paths())

View file

@ -27,7 +27,6 @@
#include <mapnik/grid/grid_renderer_base.hpp> #include <mapnik/grid/grid_renderer_base.hpp>
#include <mapnik/grid/grid.hpp> #include <mapnik/grid/grid.hpp>
#include <mapnik/line_symbolizer.hpp>
#include <mapnik/vertex_converters.hpp> #include <mapnik/vertex_converters.hpp>
// agg // agg
@ -66,20 +65,27 @@ void grid_renderer<T>::process(line_symbolizer const& sym,
ras_ptr->reset(); ras_ptr->reset();
stroke const& stroke_ = sym.get_stroke();
agg::trans_affine tr; agg::trans_affine tr;
evaluate_transform(tr, feature, sym.get_transform()); auto transform = get_optional<transform_type>(sym, keys::geometry_transform);
if (transform) { evaluate_transform(tr, feature, *transform); }
box2d<double> clipping_extent = query_extent_; box2d<double> clipping_extent = query_extent_;
if (sym.clip())
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 has_dash = has_key<dash_array>(sym, keys::stroke_dasharray);
if (clip)
{ {
double padding = (double)(query_extent_.width()/pixmap_.width()); double padding = (double)(query_extent_.width()/pixmap_.width());
double half_stroke = stroke_.get_width()/2.0; double half_stroke = width/2.0;
if (half_stroke > 1) if (half_stroke > 1)
padding *= half_stroke; padding *= half_stroke;
if (std::fabs(sym.offset()) > 0) if (std::fabs(offset) > 0)
padding *= std::fabs(sym.offset()) * 1.2; padding *= std::fabs(offset) * 1.2;
padding *= scale_factor_; padding *= scale_factor_;
clipping_extent.pad(padding); clipping_extent.pad(padding);
} }
@ -87,13 +93,13 @@ void grid_renderer<T>::process(line_symbolizer const& sym,
vertex_converter<box2d<double>, grid_rasterizer, line_symbolizer, vertex_converter<box2d<double>, grid_rasterizer, line_symbolizer,
CoordTransform, proj_transform, agg::trans_affine, conv_types> CoordTransform, proj_transform, agg::trans_affine, conv_types>
converter(clipping_extent,*ras_ptr,sym,t_,prj_trans,tr,scale_factor_); converter(clipping_extent,*ras_ptr,sym,t_,prj_trans,tr,scale_factor_);
if (sym.clip()) converter.set<clip_line_tag>(); // optional clip (default: true) if (clip) converter.set<clip_line_tag>(); // optional clip (default: true)
converter.set<transform_tag>(); // always transform converter.set<transform_tag>(); // always transform
if (std::fabs(sym.offset()) > 0.0) converter.set<offset_transform_tag>(); // parallel offset if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset
converter.set<affine_transform_tag>(); // optional affine transform converter.set<affine_transform_tag>(); // optional affine transform
if (sym.simplify_tolerance() > 0.0) converter.set<simplify_tag>(); // optional simplify converter if (simplify_tolerance > 0.0) converter.set<simplify_tag>(); // optional simplify converter
if (sym.smooth() > 0.0) converter.set<smooth_tag>(); // optional smooth converter if (smooth > 0.0) converter.set<smooth_tag>(); // optional smooth converter
if (stroke_.has_dash()) converter.set<dash_tag>(); if (has_dash) converter.set<dash_tag>();
converter.set<stroke_tag>(); //always stroke converter.set<stroke_tag>(); //always stroke
for ( geometry_type & geom : feature.paths()) for ( geometry_type & geom : feature.paths())

View file

@ -59,7 +59,6 @@ porting notes -->
#include <mapnik/svg/svg_storage.hpp> #include <mapnik/svg/svg_storage.hpp>
#include <mapnik/svg/svg_path_adapter.hpp> #include <mapnik/svg/svg_path_adapter.hpp>
#include <mapnik/svg/svg_path_attributes.hpp> #include <mapnik/svg/svg_path_attributes.hpp>
#include <mapnik/markers_symbolizer.hpp>
#include <mapnik/parse_path.hpp> #include <mapnik/parse_path.hpp>
// agg // agg
@ -87,7 +86,9 @@ void grid_renderer<T>::process(markers_symbolizer const& sym,
typedef label_collision_detector4 detector_type; typedef label_collision_detector4 detector_type;
typedef boost::mpl::vector<clip_poly_tag,transform_tag,smooth_tag> conv_types; typedef boost::mpl::vector<clip_poly_tag,transform_tag,smooth_tag> conv_types;
std::string filename = path_processor_type::evaluate(*sym.get_filename(), feature); 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);
if (!filename.empty()) if (!filename.empty())
{ {
@ -96,8 +97,11 @@ void grid_renderer<T>::process(markers_symbolizer const& sym,
{ {
ras_ptr->reset(); ras_ptr->reset();
agg::trans_affine geom_tr; agg::trans_affine geom_tr;
evaluate_transform(geom_tr, feature, sym.get_transform()); auto geom_transform = get_optional<transform_type>(sym, keys::geometry_transform);
if (geom_transform) { evaluate_transform(geom_tr, feature, *geom_transform); }
agg::trans_affine tr = agg::trans_affine_scaling(scale_factor_*(1.0/pixmap_.get_resolution())); agg::trans_affine tr = agg::trans_affine_scaling(scale_factor_*(1.0/pixmap_.get_resolution()));
auto img_transform = get_optional<transform_type>(sym, keys::image_transform);
if ((*mark)->is_vector()) if ((*mark)->is_vector())
{ {
@ -113,8 +117,9 @@ void grid_renderer<T>::process(markers_symbolizer const& sym,
detector_type, detector_type,
mapnik::grid > dispatch_type; mapnik::grid > dispatch_type;
boost::optional<svg_path_ptr> const& stock_vector_marker = (*mark)->get_vector_data(); boost::optional<svg_path_ptr> const& stock_vector_marker = (*mark)->get_vector_data();
expression_ptr const& width_expr = sym.get_width();
expression_ptr const& height_expr = sym.get_height(); auto width_expr = get_optional<expression_ptr>(sym, keys::width);
auto height_expr = get_optional<expression_ptr>(sym, keys::height);
// special case for simple ellipse markers // special case for simple ellipse markers
// to allow for full control over rx/ry dimensions // to allow for full control over rx/ry dimensions
@ -129,7 +134,8 @@ void grid_renderer<T>::process(markers_symbolizer const& sym,
svg_attribute_type attributes; svg_attribute_type attributes;
bool result = push_explicit_style( (*stock_vector_marker)->attributes(), attributes, sym); bool result = push_explicit_style( (*stock_vector_marker)->attributes(), attributes, sym);
svg_renderer_type svg_renderer(svg_path, result ? attributes : (*stock_vector_marker)->attributes()); svg_renderer_type svg_renderer(svg_path, result ? attributes : (*stock_vector_marker)->attributes());
evaluate_transform(tr, feature, sym.get_image_transform()); if (img_transform) { evaluate_transform(tr, feature, *img_transform); }
box2d<double> bbox = marker_ellipse.bounding_box(); box2d<double> bbox = marker_ellipse.bounding_box();
coord2d center = bbox.center(); coord2d center = bbox.center();
agg::trans_affine_translation recenter(-center.x, -center.y); agg::trans_affine_translation recenter(-center.x, -center.y);
@ -148,7 +154,7 @@ void grid_renderer<T>::process(markers_symbolizer const& sym,
vertex_converter<box2d<double>, dispatch_type, markers_symbolizer, vertex_converter<box2d<double>, dispatch_type, markers_symbolizer,
CoordTransform, proj_transform, agg::trans_affine, conv_types> CoordTransform, proj_transform, agg::trans_affine, conv_types>
converter(query_extent_, rasterizer_dispatch, sym,t_,prj_trans,tr,scale_factor_); converter(query_extent_, rasterizer_dispatch, sym,t_,prj_trans,tr,scale_factor_);
if (sym.clip() && feature.paths().size() > 0) // optional clip (default: true) if (clip && feature.paths().size() > 0) // optional clip (default: true)
{ {
geometry_type::types type = feature.paths()[0].type(); geometry_type::types type = feature.paths()[0].type();
if (type == geometry_type::types::Polygon) if (type == geometry_type::types::Polygon)
@ -159,14 +165,15 @@ void grid_renderer<T>::process(markers_symbolizer const& sym,
// don't clip if type==Point // don't clip if type==Point
} }
converter.template set<transform_tag>(); //always transform converter.template set<transform_tag>(); //always transform
if (sym.smooth() > 0.0) converter.template set<smooth_tag>(); // optional smooth converter if (smooth > 0.0) converter.template set<smooth_tag>(); // optional smooth converter
apply_markers_multi(feature, converter, sym); apply_markers_multi(feature, converter, sym);
} }
else else
{ {
box2d<double> const& bbox = (*mark)->bounding_box(); box2d<double> const& bbox = (*mark)->bounding_box();
setup_transform_scaling(tr, bbox.width(), bbox.height(), feature, sym); setup_transform_scaling(tr, bbox.width(), bbox.height(), feature, sym);
evaluate_transform(tr, feature, sym.get_image_transform()); if (img_transform) { evaluate_transform(tr, feature, *img_transform); }
// TODO - clamping to >= 4 pixels // TODO - clamping to >= 4 pixels
coord2d center = bbox.center(); coord2d center = bbox.center();
agg::trans_affine_translation recenter(-center.x, -center.y); agg::trans_affine_translation recenter(-center.x, -center.y);
@ -190,7 +197,7 @@ void grid_renderer<T>::process(markers_symbolizer const& sym,
vertex_converter<box2d<double>, dispatch_type, markers_symbolizer, vertex_converter<box2d<double>, dispatch_type, markers_symbolizer,
CoordTransform, proj_transform, agg::trans_affine, conv_types> CoordTransform, proj_transform, agg::trans_affine, conv_types>
converter(query_extent_, rasterizer_dispatch, sym,t_,prj_trans,tr,scale_factor_); converter(query_extent_, rasterizer_dispatch, sym,t_,prj_trans,tr,scale_factor_);
if (sym.clip() && feature.paths().size() > 0) // optional clip (default: true) if (clip && feature.paths().size() > 0) // optional clip (default: true)
{ {
geometry_type::types type = feature.paths()[0].type(); geometry_type::types type = feature.paths()[0].type();
if (type == geometry_type::types::Polygon) if (type == geometry_type::types::Polygon)
@ -201,14 +208,15 @@ void grid_renderer<T>::process(markers_symbolizer const& sym,
// don't clip if type==Point // don't clip if type==Point
} }
converter.template set<transform_tag>(); //always transform converter.template set<transform_tag>(); //always transform
if (sym.smooth() > 0.0) converter.template set<smooth_tag>(); // optional smooth converter if (smooth > 0.0) converter.template set<smooth_tag>(); // optional smooth converter
apply_markers_multi(feature, converter, sym); apply_markers_multi(feature, converter, sym);
} }
} }
else // raster markers else // raster markers
{ {
setup_transform_scaling(tr, (*mark)->width(), (*mark)->height(), feature, sym); setup_transform_scaling(tr, (*mark)->width(), (*mark)->height(), feature, sym);
evaluate_transform(tr, feature, sym.get_image_transform()); if (img_transform) { evaluate_transform(tr, feature, *img_transform); }
box2d<double> const& bbox = (*mark)->bounding_box(); box2d<double> const& bbox = (*mark)->bounding_box();
// - clamp sizes to > 4 pixels of interactivity // - clamp sizes to > 4 pixels of interactivity
coord2d center = bbox.center(); coord2d center = bbox.center();
@ -235,7 +243,7 @@ void grid_renderer<T>::process(markers_symbolizer const& sym,
vertex_converter<box2d<double>, dispatch_type, markers_symbolizer, vertex_converter<box2d<double>, dispatch_type, markers_symbolizer,
CoordTransform, proj_transform, agg::trans_affine, conv_types> CoordTransform, proj_transform, agg::trans_affine, conv_types>
converter(query_extent_, rasterizer_dispatch, sym,t_,prj_trans,tr,scale_factor_); converter(query_extent_, rasterizer_dispatch, sym,t_,prj_trans,tr,scale_factor_);
if (sym.clip() && feature.paths().size() > 0) // optional clip (default: true) if (clip && feature.paths().size() > 0) // optional clip (default: true)
{ {
geometry_type::types type = feature.paths()[0].type(); geometry_type::types type = feature.paths()[0].type();
if (type == geometry_type::types::Polygon) if (type == geometry_type::types::Polygon)
@ -246,7 +254,7 @@ void grid_renderer<T>::process(markers_symbolizer const& sym,
// don't clip if type==Point // don't clip if type==Point
} }
converter.template set<transform_tag>(); //always transform converter.template set<transform_tag>(); //always transform
if (sym.smooth() > 0.0) converter.template set<smooth_tag>(); // optional smooth converter if (smooth > 0.0) converter.template set<smooth_tag>(); // optional smooth converter
apply_markers_multi(feature, converter, sym); apply_markers_multi(feature, converter, sym);
} }
} }

View file

@ -29,7 +29,6 @@
#include <mapnik/geom_util.hpp> #include <mapnik/geom_util.hpp>
#include <mapnik/label_collision_detector.hpp> #include <mapnik/label_collision_detector.hpp>
#include <mapnik/point_symbolizer.hpp>
#include <mapnik/marker.hpp> #include <mapnik/marker.hpp>
#include <mapnik/marker_cache.hpp> #include <mapnik/marker_cache.hpp>
#include <mapnik/parse_path.hpp> #include <mapnik/parse_path.hpp>
@ -50,7 +49,7 @@ void grid_renderer<T>::process(point_symbolizer const& sym,
mapnik::feature_impl & feature, mapnik::feature_impl & feature,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
std::string filename = path_processor_type::evaluate(*sym.get_filename(), feature); std::string filename = get<std::string>(sym, keys::file, feature);
boost::optional<mapnik::marker_ptr> marker; boost::optional<mapnik::marker_ptr> marker;
if ( !filename.empty() ) if ( !filename.empty() )
@ -64,11 +63,18 @@ void grid_renderer<T>::process(point_symbolizer const& sym,
if (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);
auto img_transform = get_optional<transform_type>(sym, keys::image_transform);
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, src_over);
box2d<double> const& bbox = (*marker)->bounding_box(); box2d<double> const& bbox = (*marker)->bounding_box();
coord2d center = bbox.center(); coord2d center = bbox.center();
agg::trans_affine tr; agg::trans_affine tr;
evaluate_transform(tr, feature, sym.get_image_transform()); if (img_transform) { evaluate_transform(tr, feature, *img_transform); }
tr = agg::trans_affine_scaling(scale_factor_) * tr; tr = agg::trans_affine_scaling(scale_factor_) * tr;
agg::trans_affine_translation recenter(-center.x, -center.y); agg::trans_affine_translation recenter(-center.x, -center.y);
@ -81,7 +87,7 @@ void grid_renderer<T>::process(point_symbolizer const& sym,
double x; double x;
double y; double y;
double z=0; double z=0;
if (sym.get_point_placement() == CENTROID_POINT_PLACEMENT) if (placement == CENTROID_POINT_PLACEMENT)
{ {
if (!label::centroid(geom, x, y)) if (!label::centroid(geom, x, y))
return; return;
@ -95,7 +101,7 @@ void grid_renderer<T>::process(point_symbolizer const& sym,
prj_trans.backward(x,y,z); prj_trans.backward(x,y,z);
t_.forward(&x,&y); t_.forward(&x,&y);
label_ext.re_center(x,y); label_ext.re_center(x,y);
if (sym.get_allow_overlap() || if (allow_overlap ||
detector_->has_placement(label_ext)) detector_->has_placement(label_ext))
{ {
@ -104,10 +110,10 @@ void grid_renderer<T>::process(point_symbolizer const& sym,
pixel_position(x, y), pixel_position(x, y),
**marker, **marker,
tr, tr,
sym.get_opacity(), opacity,
sym.comp_op()); comp_op);
if (!sym.get_ignore_placement()) if (!ignore_placement)
detector_->insert(label_ext); detector_->insert(label_ext);
} }
} }

View file

@ -29,7 +29,6 @@
#include <mapnik/grid/grid_renderer.hpp> #include <mapnik/grid/grid_renderer.hpp>
#include <mapnik/grid/grid_renderer_base.hpp> #include <mapnik/grid/grid_renderer_base.hpp>
#include <mapnik/grid/grid.hpp> #include <mapnik/grid/grid.hpp>
#include <mapnik/polygon_pattern_symbolizer.hpp>
#include <mapnik/vertex_converters.hpp> #include <mapnik/vertex_converters.hpp>
#include <mapnik/marker.hpp> #include <mapnik/marker.hpp>
#include <mapnik/marker_cache.hpp> #include <mapnik/marker_cache.hpp>
@ -51,7 +50,7 @@ void grid_renderer<T>::process(polygon_pattern_symbolizer const& sym,
mapnik::feature_impl & feature, mapnik::feature_impl & feature,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
std::string filename = path_processor_type::evaluate( *sym.get_filename(), feature); std::string filename = get<std::string>(sym, keys::file, feature);
boost::optional<marker_ptr> mark = marker_cache::instance().find(filename,true); boost::optional<marker_ptr> mark = marker_cache::instance().find(filename,true);
if (!mark) return; if (!mark) return;
@ -67,19 +66,24 @@ void grid_renderer<T>::process(polygon_pattern_symbolizer const& sym,
ras_ptr->reset(); ras_ptr->reset();
bool clip = get<value_bool>(sym, keys::clip, feature, false);
double simplify_tolerance = get<value_double>(sym, keys::simplify_tolerance, feature, 0.0);
double smooth = get<value_double>(sym, keys::smooth, feature, false);
agg::trans_affine tr; agg::trans_affine tr;
evaluate_transform(tr, feature, sym.get_transform()); auto geom_transform = get_optional<transform_type>(sym, keys::geometry_transform);
if (geom_transform) evaluate_transform(tr, feature, *geom_transform);
typedef boost::mpl::vector<clip_poly_tag,transform_tag,affine_transform_tag,smooth_tag> conv_types; typedef boost::mpl::vector<clip_poly_tag,transform_tag,affine_transform_tag,smooth_tag> conv_types;
vertex_converter<box2d<double>, grid_rasterizer, polygon_pattern_symbolizer, vertex_converter<box2d<double>, grid_rasterizer, polygon_pattern_symbolizer,
CoordTransform, proj_transform, agg::trans_affine, conv_types> CoordTransform, proj_transform, agg::trans_affine, conv_types>
converter(query_extent_,*ras_ptr,sym,t_,prj_trans,tr,scale_factor_); converter(query_extent_,*ras_ptr,sym,t_,prj_trans,tr,scale_factor_);
if (prj_trans.equal() && sym.clip()) converter.set<clip_poly_tag>(); //optional clip (default: true) if (prj_trans.equal() && clip) converter.set<clip_poly_tag>(); //optional clip (default: true)
converter.set<transform_tag>(); //always transform converter.set<transform_tag>(); //always transform
converter.set<affine_transform_tag>(); converter.set<affine_transform_tag>();
if (sym.smooth() > 0.0) converter.set<smooth_tag>(); // optional smooth converter if (simplify_tolerance > 0.0) converter.set<simplify_tag>(); // optional simplify converter
if (smooth > 0.0) converter.set<smooth_tag>(); // optional smooth converter
for ( geometry_type & geom : feature.paths()) for ( geometry_type & geom : feature.paths())
{ {

View file

@ -29,7 +29,6 @@
#include <mapnik/grid/grid_renderer.hpp> #include <mapnik/grid/grid_renderer.hpp>
#include <mapnik/grid/grid_renderer_base.hpp> #include <mapnik/grid/grid_renderer_base.hpp>
#include <mapnik/grid/grid.hpp> #include <mapnik/grid/grid.hpp>
#include <mapnik/polygon_symbolizer.hpp>
#include <mapnik/vertex_converters.hpp> #include <mapnik/vertex_converters.hpp>
// agg // agg
@ -55,18 +54,23 @@ void grid_renderer<T>::process(polygon_symbolizer const& sym,
ras_ptr->reset(); ras_ptr->reset();
agg::trans_affine tr; agg::trans_affine tr;
evaluate_transform(tr, feature, sym.get_transform()); auto geom_transform = get_optional<transform_type>(sym, keys::geometry_transform);
if (geom_transform) evaluate_transform(tr, feature, *geom_transform);
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);
typedef boost::mpl::vector<clip_poly_tag,transform_tag,affine_transform_tag,simplify_tag,smooth_tag> conv_types; typedef boost::mpl::vector<clip_poly_tag,transform_tag,affine_transform_tag,simplify_tag,smooth_tag> conv_types;
vertex_converter<box2d<double>, grid_rasterizer, polygon_symbolizer, vertex_converter<box2d<double>, grid_rasterizer, polygon_symbolizer,
CoordTransform, proj_transform, agg::trans_affine, conv_types> CoordTransform, proj_transform, agg::trans_affine, conv_types>
converter(query_extent_,*ras_ptr,sym,t_,prj_trans,tr,scale_factor_); converter(query_extent_,*ras_ptr,sym,t_,prj_trans,tr,scale_factor_);
if (prj_trans.equal() && sym.clip()) converter.set<clip_poly_tag>(); //optional clip (default: true) if (prj_trans.equal() && clip) converter.set<clip_poly_tag>(); //optional clip (default: true)
converter.set<transform_tag>(); //always transform converter.set<transform_tag>(); //always transform
converter.set<affine_transform_tag>(); converter.set<affine_transform_tag>();
if (sym.simplify_tolerance() > 0.0) converter.set<simplify_tag>(); // optional simplify converter if (simplify_tolerance > 0.0) converter.set<simplify_tag>(); // optional simplify converter
if (sym.smooth() > 0.0) converter.set<smooth_tag>(); // optional smooth converter if (smooth > 0.0) converter.set<smooth_tag>(); // optional smooth converter
for ( geometry_type & geom : feature.paths()) for ( geometry_type & geom : feature.paths())

View file

@ -27,9 +27,9 @@
#include <mapnik/grid/grid_renderer.hpp> #include <mapnik/grid/grid_renderer.hpp>
#include <mapnik/grid/grid_renderer_base.hpp> #include <mapnik/grid/grid_renderer_base.hpp>
#include <mapnik/grid/grid.hpp> #include <mapnik/grid/grid.hpp>
#include <mapnik/symbolizer_helpers.hpp> #include <mapnik/text/symbolizer_helpers.hpp>
#include <mapnik/pixel_position.hpp> #include <mapnik/pixel_position.hpp>
#include <mapnik/font_util.hpp> #include <mapnik/text/renderer.hpp>
// agg // agg
#include "agg_trans_affine.h" #include "agg_trans_affine.h"
@ -41,8 +41,7 @@ void grid_renderer<T>::process(shield_symbolizer const& sym,
mapnik::feature_impl & feature, mapnik::feature_impl & feature,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
shield_symbolizer_helper<face_manager<freetype_engine>, text_symbolizer_helper helper(
label_collision_detector4> helper(
sym, feature, prj_trans, sym, feature, prj_trans,
width_, height_, width_, height_,
scale_factor_, scale_factor_,
@ -50,41 +49,34 @@ void grid_renderer<T>::process(shield_symbolizer const& sym,
query_extent_); query_extent_);
bool placement_found = false; bool placement_found = false;
text_renderer<T> ren(pixmap_, composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, src_over);
font_manager_, double opacity = get<double>(sym,keys::opacity,feature, 1.0);
sym.get_halo_rasterizer(),
sym.comp_op(),
scale_factor_);
text_placement_info_ptr placement; grid_text_renderer<T> ren(pixmap_,
while (helper.next()) comp_op,
scale_factor_);
placements_list const& placements = helper.get();
value_integer feature_id = feature.id();
for (glyph_positions_ptr glyphs : placements)
{ {
placement_found = true; if (glyphs->marker())
placements_type const& placements = helper.placements();
for (unsigned int ii = 0; ii < placements.size(); ++ii)
{ {
// get_marker_position returns (minx,miny) corner position, render_marker(feature,
// while (currently only) agg_renderer::render_marker newly
// expects center position;
// until all renderers and shield_symbolizer_helper are
// modified accordingly, we must adjust the position here
pixel_position pos = helper.get_marker_position(placements[ii]);
pos.x += 0.5 * helper.get_marker_width();
pos.y += 0.5 * helper.get_marker_height();
render_marker(feature,
pixmap_.get_resolution(), pixmap_.get_resolution(),
pos, glyphs->marker_pos(),
helper.get_marker(), *(glyphs->marker()->marker),
helper.get_image_transform(), glyphs->marker()->transform,
sym.get_opacity(), opacity, comp_op);
sym.comp_op());
ren.prepare_glyphs(placements[ii]);
ren.render_id(feature.id(), placements[ii].center);
} }
ren.render(*glyphs, feature_id);
placement_found = true;
} }
if (placement_found) if (placement_found)
{
pixmap_.add_feature(feature); pixmap_.add_feature(feature);
}
} }
template void grid_renderer<grid>::process(shield_symbolizer const&, template void grid_renderer<grid>::process(shield_symbolizer const&,

View file

@ -23,8 +23,9 @@
// mapnik // mapnik
#include <mapnik/feature.hpp> #include <mapnik/feature.hpp>
#include <mapnik/grid/grid_renderer.hpp> #include <mapnik/grid/grid_renderer.hpp>
#include <mapnik/symbolizer_helpers.hpp> #include <mapnik/text/symbolizer_helpers.hpp>
#include <mapnik/font_util.hpp> #include <mapnik/pixel_position.hpp>
#include <mapnik/text/renderer.hpp>
namespace mapnik { namespace mapnik {
@ -33,8 +34,7 @@ void grid_renderer<T>::process(text_symbolizer const& sym,
mapnik::feature_impl & feature, mapnik::feature_impl & feature,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
text_symbolizer_helper<face_manager<freetype_engine>, text_symbolizer_helper helper(
label_collision_detector4> helper(
sym, feature, prj_trans, sym, feature, prj_trans,
width_, height_, width_, height_,
scale_factor_ * (1.0/pixmap_.get_resolution()), scale_factor_ * (1.0/pixmap_.get_resolution()),
@ -42,23 +42,24 @@ void grid_renderer<T>::process(text_symbolizer const& sym,
query_extent_); query_extent_);
bool placement_found = false; bool placement_found = false;
text_renderer<T> ren(pixmap_, composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, src_over);
font_manager_,
sym.get_halo_rasterizer(),
sym.comp_op(),
scale_factor_);
while (helper.next()) { grid_text_renderer<T> ren(pixmap_,
comp_op,
scale_factor_);
placements_list const& placements = helper.get();
value_integer feature_id = feature.id();
for (glyph_positions_ptr glyphs : placements)
{
ren.render(*glyphs, feature_id);
placement_found = true; placement_found = true;
placements_type const& placements = helper.placements();
for (unsigned int ii = 0; ii < placements.size(); ++ii)
{
ren.prepare_glyphs(placements[ii]);
ren.render_id(feature.id(), placements[ii].center);
}
} }
if (placement_found) pixmap_.add_feature(feature); if (placement_found)
{
pixmap_.add_feature(feature);
}
} }
template void grid_renderer<grid>::process(text_symbolizer const&, template void grid_renderer<grid>::process(text_symbolizer const&,