Factored out markers symbolizer logic.
It's not ideal - there's still a bunch of "dispatch" objects from which the common elements could be factored for greater readability.
This commit is contained in:
parent
f01953e8f7
commit
dd9584bdd6
7 changed files with 380 additions and 491 deletions
|
@ -73,6 +73,14 @@ struct raster_markers_rasterizer_dispatch_grid
|
|||
//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)
|
||||
{
|
||||
|
@ -185,23 +193,26 @@ private:
|
|||
template <typename BufferType, typename SvgRenderer, typename Rasterizer, typename Detector, typename PixMapType>
|
||||
struct vector_markers_rasterizer_dispatch_grid
|
||||
{
|
||||
typedef typename SvgRenderer::renderer_base renderer_base;
|
||||
typedef typename renderer_base::pixfmt_type pixfmt_type;
|
||||
typedef typename SvgRenderer::renderer_base renderer_base;
|
||||
typedef typename SvgRenderer::vertex_source_type vertex_source_type;
|
||||
typedef typename SvgRenderer::attribute_source_type attribute_source_type;
|
||||
typedef typename renderer_base::pixfmt_type pixfmt_type;
|
||||
|
||||
vector_markers_rasterizer_dispatch_grid(BufferType & render_buffer,
|
||||
SvgRenderer & svg_renderer,
|
||||
Rasterizer & ras,
|
||||
box2d<double> const& bbox,
|
||||
agg::trans_affine const& marker_trans,
|
||||
markers_symbolizer const& sym,
|
||||
Detector & detector,
|
||||
double scale_factor,
|
||||
mapnik::feature_impl & feature,
|
||||
PixMapType & pixmap)
|
||||
vertex_source_type &path,
|
||||
const attribute_source_type &attrs,
|
||||
Rasterizer & ras,
|
||||
box2d<double> const& bbox,
|
||||
agg::trans_affine const& marker_trans,
|
||||
markers_symbolizer const& sym,
|
||||
Detector & detector,
|
||||
double scale_factor,
|
||||
mapnik::feature_impl & feature,
|
||||
PixMapType & pixmap)
|
||||
: buf_(render_buffer),
|
||||
pixf_(buf_),
|
||||
renb_(pixf_),
|
||||
svg_renderer_(svg_renderer),
|
||||
svg_renderer_(path, attrs),
|
||||
ras_(ras),
|
||||
bbox_(bbox),
|
||||
marker_trans_(marker_trans),
|
||||
|
@ -216,6 +227,14 @@ struct vector_markers_rasterizer_dispatch_grid
|
|||
//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)
|
||||
{
|
||||
|
@ -290,7 +309,7 @@ private:
|
|||
BufferType & buf_;
|
||||
pixfmt_type pixf_;
|
||||
renderer_base renb_;
|
||||
SvgRenderer & svg_renderer_;
|
||||
SvgRenderer svg_renderer_;
|
||||
Rasterizer & ras_;
|
||||
box2d<double> const& bbox_;
|
||||
agg::trans_affine const& marker_trans_;
|
||||
|
|
|
@ -61,11 +61,14 @@ namespace mapnik {
|
|||
template <typename BufferType, typename SvgRenderer, typename Rasterizer, typename Detector>
|
||||
struct vector_markers_rasterizer_dispatch
|
||||
{
|
||||
typedef typename SvgRenderer::renderer_base renderer_base;
|
||||
typedef typename renderer_base::pixfmt_type pixfmt_type;
|
||||
typedef typename SvgRenderer::renderer_base renderer_base;
|
||||
typedef typename SvgRenderer::vertex_source_type vertex_source_type;
|
||||
typedef typename SvgRenderer::attribute_source_type attribute_source_type;
|
||||
typedef typename renderer_base::pixfmt_type pixfmt_type;
|
||||
|
||||
vector_markers_rasterizer_dispatch(BufferType & render_buffer,
|
||||
SvgRenderer & svg_renderer,
|
||||
vertex_source_type &path,
|
||||
attribute_source_type const &attrs,
|
||||
Rasterizer & ras,
|
||||
box2d<double> const& bbox,
|
||||
agg::trans_affine const& marker_trans,
|
||||
|
@ -76,7 +79,7 @@ struct vector_markers_rasterizer_dispatch
|
|||
: buf_(render_buffer),
|
||||
pixf_(buf_),
|
||||
renb_(pixf_),
|
||||
svg_renderer_(svg_renderer),
|
||||
svg_renderer_(path, attrs),
|
||||
ras_(ras),
|
||||
bbox_(bbox),
|
||||
marker_trans_(marker_trans),
|
||||
|
@ -88,6 +91,13 @@ struct vector_markers_rasterizer_dispatch
|
|||
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_)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void add_path(T & path)
|
||||
{
|
||||
|
@ -162,7 +172,7 @@ private:
|
|||
BufferType & buf_;
|
||||
pixfmt_type pixf_;
|
||||
renderer_base renb_;
|
||||
SvgRenderer & svg_renderer_;
|
||||
SvgRenderer svg_renderer_;
|
||||
Rasterizer & ras_;
|
||||
box2d<double> const& bbox_;
|
||||
agg::trans_affine const& marker_trans_;
|
||||
|
@ -204,6 +214,13 @@ struct raster_markers_rasterizer_dispatch
|
|||
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_)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void add_path(T & path)
|
||||
{
|
||||
|
|
176
include/mapnik/renderer_common/process_markers_symbolizer.hpp
Normal file
176
include/mapnik/renderer_common/process_markers_symbolizer.hpp
Normal file
|
@ -0,0 +1,176 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2013 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_RENDERER_COMMON_PROCESS_MARKERS_SYMBOLIZER_HPP
|
||||
#define MAPNIK_RENDERER_COMMON_PROCESS_MARKERS_SYMBOLIZER_HPP
|
||||
|
||||
#include <mapnik/svg/svg_storage.hpp>
|
||||
#include <mapnik/svg/svg_path_adapter.hpp>
|
||||
#include <mapnik/svg/svg_path_attributes.hpp>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
template <typename F1, typename F2>
|
||||
void render_markers_symbolizer(markers_symbolizer const &sym,
|
||||
mapnik::feature_impl &feature,
|
||||
proj_transform const &prj_trans,
|
||||
renderer_common &common,
|
||||
box2d<double> const &clip_box,
|
||||
F1 make_vector_dispatch,
|
||||
F2 make_raster_dispatch)
|
||||
{
|
||||
using namespace mapnik::svg;
|
||||
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);
|
||||
|
||||
// https://github.com/mapnik/mapnik/issues/1316
|
||||
bool snap_pixels = !mapnik::marker_cache::instance().is_uri(filename);
|
||||
if (!filename.empty())
|
||||
{
|
||||
boost::optional<marker_ptr> mark = mapnik::marker_cache::instance().find(filename, true);
|
||||
if (mark && *mark)
|
||||
{
|
||||
agg::trans_affine tr = agg::trans_affine_scaling(common.scale_factor_);
|
||||
|
||||
if ((*mark)->is_vector())
|
||||
{
|
||||
boost::optional<svg_path_ptr> const& stock_vector_marker = (*mark)->get_vector_data();
|
||||
|
||||
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
|
||||
// to allow for full control over rx/ry dimensions
|
||||
if (filename == "shape://ellipse"
|
||||
&& (width_expr || height_expr))
|
||||
{
|
||||
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);
|
||||
svg_attribute_type attributes;
|
||||
bool result = push_explicit_style( (*stock_vector_marker)->attributes(), attributes, sym);
|
||||
auto image_transform = get_optional<transform_type>(sym, keys::image_transform);
|
||||
if (image_transform) evaluate_transform(tr, feature, *image_transform);
|
||||
box2d<double> bbox = marker_ellipse.bounding_box();
|
||||
|
||||
auto rasterizer_dispatch = make_vector_dispatch(
|
||||
svg_path, result ? attributes : (*stock_vector_marker)->attributes(),
|
||||
marker_ellipse, bbox, tr, snap_pixels);
|
||||
typedef decltype(rasterizer_dispatch) dispatch_type;
|
||||
|
||||
vertex_converter<box2d<double>, dispatch_type, markers_symbolizer,
|
||||
CoordTransform, proj_transform, agg::trans_affine, conv_types>
|
||||
converter(clip_box, rasterizer_dispatch, sym,common.t_,prj_trans,tr,common.scale_factor_);
|
||||
if (clip && feature.paths().size() > 0) // optional clip (default: true)
|
||||
{
|
||||
geometry_type::types type = feature.paths()[0].type();
|
||||
if (type == geometry_type::types::Polygon)
|
||||
converter.template set<clip_poly_tag>();
|
||||
// line clipping disabled due to https://github.com/mapnik/mapnik/issues/1426
|
||||
//else if (type == LineString)
|
||||
// converter.template set<clip_line_tag>();
|
||||
// don't clip if type==Point
|
||||
}
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
box2d<double> const& bbox = (*mark)->bounding_box();
|
||||
setup_transform_scaling(tr, bbox.width(), bbox.height(), feature, sym);
|
||||
auto image_transform = get_optional<transform_type>(sym, keys::image_transform);
|
||||
if (image_transform) evaluate_transform(tr, feature, *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);
|
||||
auto rasterizer_dispatch = make_vector_dispatch(
|
||||
svg_path, result ? attributes : (*stock_vector_marker)->attributes(),
|
||||
**stock_vector_marker, bbox, tr, snap_pixels);
|
||||
typedef decltype(rasterizer_dispatch) dispatch_type;
|
||||
|
||||
vertex_converter<box2d<double>, dispatch_type, markers_symbolizer,
|
||||
CoordTransform, proj_transform, agg::trans_affine, conv_types>
|
||||
converter(clip_box, rasterizer_dispatch, sym,common.t_,prj_trans,tr,common.scale_factor_);
|
||||
if (clip && feature.paths().size() > 0) // optional clip (default: true)
|
||||
{
|
||||
geometry_type::types type = feature.paths()[0].type();
|
||||
if (type == geometry_type::types::Polygon)
|
||||
converter.template set<clip_poly_tag>();
|
||||
// line clipping disabled due to https://github.com/mapnik/mapnik/issues/1426
|
||||
//else if (type == LineString)
|
||||
// converter.template set<clip_line_tag>();
|
||||
// don't clip if type==Point
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
else // raster markers
|
||||
{
|
||||
setup_transform_scaling(tr, (*mark)->width(), (*mark)->height(), feature, sym);
|
||||
auto image_transform = get_optional<transform_type>(sym, keys::image_transform);
|
||||
if (image_transform) evaluate_transform(tr, feature, *image_transform);
|
||||
box2d<double> const& bbox = (*mark)->bounding_box();
|
||||
boost::optional<mapnik::image_ptr> marker = (*mark)->get_bitmap_data();
|
||||
|
||||
auto rasterizer_dispatch = make_raster_dispatch(**marker, tr, bbox);
|
||||
typedef decltype(rasterizer_dispatch) dispatch_type;
|
||||
|
||||
vertex_converter<box2d<double>, dispatch_type, markers_symbolizer,
|
||||
CoordTransform, proj_transform, agg::trans_affine, conv_types>
|
||||
converter(clip_box, rasterizer_dispatch, sym,common.t_,prj_trans,tr,common.scale_factor_);
|
||||
|
||||
if (clip && feature.paths().size() > 0) // optional clip (default: true)
|
||||
{
|
||||
geometry_type::types type = feature.paths()[0].type();
|
||||
if (type == geometry_type::types::Polygon)
|
||||
converter.template set<clip_poly_tag>();
|
||||
// line clipping disabled due to https://github.com/mapnik/mapnik/issues/1426
|
||||
//else if (type == geometry_type::types::LineString)
|
||||
// converter.template set<clip_line_tag>();
|
||||
// don't clip if type==geometry_type::types::Point
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mapnik
|
||||
|
||||
#endif /* MAPNIK_RENDERER_COMMON_PROCESS_MARKERS_SYMBOLIZER_HPP */
|
|
@ -107,6 +107,8 @@ public:
|
|||
typedef agg::conv_transform<curved_type> curved_trans_type;
|
||||
typedef agg::conv_contour<curved_trans_type> curved_trans_contour_type;
|
||||
typedef agg::renderer_base<PixelFormat> renderer_base;
|
||||
typedef VertexSource vertex_source_type;
|
||||
typedef AttributeSource attribute_source_type;
|
||||
|
||||
svg_renderer_agg(VertexSource & source, AttributeSource const& attributes)
|
||||
: source_(source),
|
||||
|
@ -114,6 +116,10 @@ public:
|
|||
curved_stroked_(curved_),
|
||||
attributes_(attributes) {}
|
||||
|
||||
svg_renderer_agg(svg_renderer_agg &&r)
|
||||
: source_(r.source_), curved_(source_), curved_stroked_(curved_),
|
||||
attributes_(r.attributes_) {}
|
||||
|
||||
template <typename Rasterizer, typename Scanline, typename Renderer>
|
||||
void render_gradient(Rasterizer& ras,
|
||||
Scanline& sl,
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include <mapnik/svg/svg_path_attributes.hpp>
|
||||
#include <mapnik/symbolizer.hpp>
|
||||
#include <mapnik/parse_path.hpp>
|
||||
#include <mapnik/renderer_common/process_markers_symbolizer.hpp>
|
||||
|
||||
// agg
|
||||
#include "agg_basics.h"
|
||||
|
@ -63,183 +64,71 @@ void agg_renderer<T0,T1>::process(markers_symbolizer const& sym,
|
|||
feature_impl & feature,
|
||||
proj_transform const& prj_trans)
|
||||
{
|
||||
using namespace mapnik::svg;
|
||||
typedef agg::rgba8 color_type;
|
||||
typedef agg::order_rgba order_type;
|
||||
typedef agg::comp_op_adaptor_rgba_pre<color_type, order_type> blender_type; // comp blender
|
||||
typedef agg::rendering_buffer buf_type;
|
||||
typedef agg::pixfmt_custom_blend_rgba<blender_type, buf_type> pixfmt_comp_type;
|
||||
typedef agg::renderer_base<pixfmt_comp_type> renderer_base;
|
||||
typedef label_collision_detector4 detector_type;
|
||||
typedef boost::mpl::vector<clip_poly_tag,transform_tag,smooth_tag> conv_types;
|
||||
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_type;
|
||||
typedef agg::pod_bvector<path_attributes> svg_attribute_type;
|
||||
typedef svg_renderer_agg<svg_path_adapter,
|
||||
svg_attribute_type,
|
||||
renderer_type,
|
||||
pixfmt_comp_type > svg_renderer_type;
|
||||
typedef vector_markers_rasterizer_dispatch<buf_type,
|
||||
svg_renderer_type,
|
||||
rasterizer,
|
||||
detector_type > vector_dispatch_type;
|
||||
typedef raster_markers_rasterizer_dispatch<buf_type,rasterizer, detector_type> raster_dispatch_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);
|
||||
|
||||
// https://github.com/mapnik/mapnik/issues/1316
|
||||
bool snap_pixels = !mapnik::marker_cache::instance().is_uri(filename);
|
||||
if (!filename.empty())
|
||||
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);
|
||||
if (gamma != gamma_ || gamma_method != gamma_method_)
|
||||
{
|
||||
boost::optional<marker_ptr> mark = mapnik::marker_cache::instance().find(filename, true);
|
||||
if (mark && *mark)
|
||||
{
|
||||
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);
|
||||
if (gamma != gamma_ || gamma_method != gamma_method_)
|
||||
{
|
||||
set_gamma_method(ras_ptr, gamma, gamma_method);
|
||||
gamma_method_ = gamma_method;
|
||||
gamma_ = gamma;
|
||||
}
|
||||
|
||||
agg::trans_affine tr = agg::trans_affine_scaling(common_.scale_factor_);
|
||||
box2d<double> clip_box = clipping_extent();
|
||||
if ((*mark)->is_vector())
|
||||
{
|
||||
using namespace mapnik::svg;
|
||||
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_type;
|
||||
typedef agg::pod_bvector<path_attributes> svg_attribute_type;
|
||||
typedef svg_renderer_agg<svg_path_adapter,
|
||||
svg_attribute_type,
|
||||
renderer_type,
|
||||
pixfmt_comp_type > svg_renderer_type;
|
||||
typedef vector_markers_rasterizer_dispatch<buf_type,
|
||||
svg_renderer_type,
|
||||
rasterizer,
|
||||
detector_type > dispatch_type;
|
||||
boost::optional<svg_path_ptr> const& stock_vector_marker = (*mark)->get_vector_data();
|
||||
|
||||
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
|
||||
// to allow for full control over rx/ry dimensions
|
||||
if (filename == "shape://ellipse"
|
||||
&& (width_expr || height_expr))
|
||||
{
|
||||
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);
|
||||
svg_attribute_type attributes;
|
||||
bool result = push_explicit_style( (*stock_vector_marker)->attributes(), attributes, sym);
|
||||
svg_renderer_type svg_renderer(svg_path, result ? attributes : (*stock_vector_marker)->attributes());
|
||||
auto image_transform = get_optional<transform_type>(sym, keys::image_transform);
|
||||
if (image_transform) evaluate_transform(tr, feature, *image_transform);
|
||||
box2d<double> bbox = marker_ellipse.bounding_box();
|
||||
coord2d center = bbox.center();
|
||||
agg::trans_affine_translation recenter(-center.x, -center.y);
|
||||
agg::trans_affine marker_trans = recenter * tr;
|
||||
buf_type render_buffer(current_buffer_->raw_data(), current_buffer_->width(), current_buffer_->height(), current_buffer_->width() * 4);
|
||||
dispatch_type rasterizer_dispatch(render_buffer,
|
||||
svg_renderer,
|
||||
*ras_ptr,
|
||||
bbox,
|
||||
marker_trans,
|
||||
sym,
|
||||
*common_.detector_,
|
||||
common_.scale_factor_,
|
||||
snap_pixels);
|
||||
vertex_converter<box2d<double>, dispatch_type, markers_symbolizer,
|
||||
CoordTransform, proj_transform, agg::trans_affine, conv_types>
|
||||
converter(clip_box, rasterizer_dispatch, sym,common_.t_,prj_trans,tr,common_.scale_factor_);
|
||||
if (clip && feature.paths().size() > 0) // optional clip (default: true)
|
||||
{
|
||||
geometry_type::types type = feature.paths()[0].type();
|
||||
if (type == geometry_type::types::Polygon)
|
||||
converter.template set<clip_poly_tag>();
|
||||
// line clipping disabled due to https://github.com/mapnik/mapnik/issues/1426
|
||||
//else if (type == LineString)
|
||||
// converter.template set<clip_line_tag>();
|
||||
// don't clip if type==Point
|
||||
}
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
box2d<double> const& bbox = (*mark)->bounding_box();
|
||||
setup_transform_scaling(tr, bbox.width(), bbox.height(), feature, sym);
|
||||
auto image_transform = get_optional<transform_type>(sym, keys::image_transform);
|
||||
if (image_transform) evaluate_transform(tr, feature, *image_transform);
|
||||
coord2d center = bbox.center();
|
||||
agg::trans_affine_translation recenter(-center.x, -center.y);
|
||||
agg::trans_affine marker_trans = recenter * tr;
|
||||
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);
|
||||
svg_renderer_type svg_renderer(svg_path, result ? attributes : (*stock_vector_marker)->attributes());
|
||||
buf_type render_buffer(current_buffer_->raw_data(), current_buffer_->width(), current_buffer_->height(), current_buffer_->width() * 4);
|
||||
dispatch_type rasterizer_dispatch(render_buffer,
|
||||
svg_renderer,
|
||||
*ras_ptr,
|
||||
bbox,
|
||||
marker_trans,
|
||||
sym,
|
||||
*common_.detector_,
|
||||
common_.scale_factor_,
|
||||
snap_pixels);
|
||||
vertex_converter<box2d<double>, dispatch_type, markers_symbolizer,
|
||||
CoordTransform, proj_transform, agg::trans_affine, conv_types>
|
||||
converter(clip_box, rasterizer_dispatch, sym,common_.t_,prj_trans,tr,common_.scale_factor_);
|
||||
if (clip && feature.paths().size() > 0) // optional clip (default: true)
|
||||
{
|
||||
geometry_type::types type = feature.paths()[0].type();
|
||||
if (type == geometry_type::types::Polygon)
|
||||
converter.template set<clip_poly_tag>();
|
||||
// line clipping disabled due to https://github.com/mapnik/mapnik/issues/1426
|
||||
//else if (type == LineString)
|
||||
// converter.template set<clip_line_tag>();
|
||||
// don't clip if type==Point
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
else // raster markers
|
||||
{
|
||||
setup_transform_scaling(tr, (*mark)->width(), (*mark)->height(), feature, sym);
|
||||
auto image_transform = get_optional<transform_type>(sym, keys::image_transform);
|
||||
if (image_transform) evaluate_transform(tr, feature, *image_transform);
|
||||
box2d<double> const& bbox = (*mark)->bounding_box();
|
||||
coord2d center = bbox.center();
|
||||
agg::trans_affine_translation recenter(-center.x, -center.y);
|
||||
agg::trans_affine marker_trans = recenter * tr;
|
||||
boost::optional<mapnik::image_ptr> marker = (*mark)->get_bitmap_data();
|
||||
typedef raster_markers_rasterizer_dispatch<buf_type,rasterizer, detector_type> dispatch_type;
|
||||
buf_type render_buffer(current_buffer_->raw_data(), current_buffer_->width(), current_buffer_->height(), current_buffer_->width() * 4);
|
||||
dispatch_type rasterizer_dispatch(render_buffer,
|
||||
*ras_ptr,
|
||||
**marker,
|
||||
marker_trans,
|
||||
sym,
|
||||
*common_.detector_,
|
||||
common_.scale_factor_,
|
||||
true /*snap rasters no matter what*/);
|
||||
vertex_converter<box2d<double>, dispatch_type, markers_symbolizer,
|
||||
CoordTransform, proj_transform, agg::trans_affine, conv_types>
|
||||
converter(clip_box, rasterizer_dispatch, sym,common_.t_,prj_trans,tr,common_.scale_factor_);
|
||||
|
||||
if (clip && feature.paths().size() > 0) // optional clip (default: true)
|
||||
{
|
||||
geometry_type::types type = feature.paths()[0].type();
|
||||
if (type == geometry_type::types::Polygon)
|
||||
converter.template set<clip_poly_tag>();
|
||||
// line clipping disabled due to https://github.com/mapnik/mapnik/issues/1426
|
||||
//else if (type == geometry_type::types::LineString)
|
||||
// converter.template set<clip_line_tag>();
|
||||
// don't clip if type==geometry_type::types::Point
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
set_gamma_method(ras_ptr, gamma, gamma_method);
|
||||
gamma_method_ = gamma_method;
|
||||
gamma_ = gamma;
|
||||
}
|
||||
|
||||
buf_type render_buffer(current_buffer_->raw_data(), current_buffer_->width(), current_buffer_->height(), current_buffer_->width() * 4);
|
||||
|
||||
ras_ptr->reset();
|
||||
box2d<double> clip_box = clipping_extent();
|
||||
|
||||
render_markers_symbolizer(
|
||||
sym, feature, prj_trans, common_, clip_box,
|
||||
[&](svg_path_adapter &path, svg_attribute_type const &attr, svg_storage_type &,
|
||||
box2d<double> const &bbox, agg::trans_affine const &tr,
|
||||
bool snap_pixels) -> vector_dispatch_type {
|
||||
coord2d center = bbox.center();
|
||||
agg::trans_affine_translation recenter(-center.x, -center.y);
|
||||
agg::trans_affine marker_trans = recenter * tr;
|
||||
return vector_dispatch_type(render_buffer,
|
||||
path, attr,
|
||||
*ras_ptr,
|
||||
bbox,
|
||||
marker_trans,
|
||||
sym,
|
||||
*common_.detector_,
|
||||
common_.scale_factor_,
|
||||
snap_pixels);
|
||||
},
|
||||
[&](image_data_32 const &marker, agg::trans_affine const &tr,
|
||||
box2d<double> const &bbox) -> raster_dispatch_type {
|
||||
coord2d center = bbox.center();
|
||||
agg::trans_affine_translation recenter(-center.x, -center.y);
|
||||
agg::trans_affine marker_trans = recenter * tr;
|
||||
return raster_dispatch_type(render_buffer,
|
||||
*ras_ptr,
|
||||
marker,
|
||||
marker_trans,
|
||||
sym,
|
||||
*common_.detector_,
|
||||
common_.scale_factor_,
|
||||
true /*snap rasters no matter what*/);
|
||||
});
|
||||
}
|
||||
|
||||
template void agg_renderer<image_32>::process(markers_symbolizer const&,
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
#include <mapnik/renderer_common/process_building_symbolizer.hpp>
|
||||
#include <mapnik/renderer_common/process_point_symbolizer.hpp>
|
||||
#include <mapnik/renderer_common/process_raster_symbolizer.hpp>
|
||||
#include <mapnik/renderer_common/process_markers_symbolizer.hpp>
|
||||
|
||||
// cairo
|
||||
#include <cairo.h>
|
||||
|
@ -880,12 +881,12 @@ template <typename Context, typename ImageMarker, typename Detector>
|
|||
struct markers_dispatch_2
|
||||
{
|
||||
markers_dispatch_2(Context & ctx,
|
||||
ImageMarker & marker,
|
||||
Detector & detector,
|
||||
markers_symbolizer const& sym,
|
||||
box2d<double> const& bbox,
|
||||
agg::trans_affine const& marker_trans,
|
||||
double scale_factor)
|
||||
ImageMarker & marker,
|
||||
Detector & detector,
|
||||
markers_symbolizer const& sym,
|
||||
box2d<double> const& bbox,
|
||||
agg::trans_affine const& marker_trans,
|
||||
double scale_factor)
|
||||
:ctx_(ctx),
|
||||
marker_(marker),
|
||||
detector_(detector),
|
||||
|
@ -935,7 +936,7 @@ struct markers_dispatch_2
|
|||
if (allow_overlap ||
|
||||
detector_.has_placement(transformed_bbox))
|
||||
{
|
||||
ctx_.add_image(matrix, *marker_, opacity);
|
||||
ctx_.add_image(matrix, marker_, opacity);
|
||||
if (!ignore_placement)
|
||||
{
|
||||
detector_.insert(transformed_bbox);
|
||||
|
@ -956,7 +957,7 @@ struct markers_dispatch_2
|
|||
matrix *= marker_trans_;
|
||||
matrix *= agg::trans_affine_rotation(angle);
|
||||
matrix *= agg::trans_affine_translation(x, y);
|
||||
ctx_.add_image(matrix, *marker_, opacity);
|
||||
ctx_.add_image(matrix, marker_, opacity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -975,135 +976,30 @@ void cairo_renderer_base::process(markers_symbolizer const& sym,
|
|||
mapnik::feature_impl & feature,
|
||||
proj_transform const& prj_trans)
|
||||
{
|
||||
typedef boost::mpl::vector<clip_poly_tag,transform_tag,smooth_tag> conv_types;
|
||||
typedef agg::pod_bvector<svg::path_attributes> svg_attribute_type;
|
||||
typedef detail::markers_dispatch_2<cairo_context, mapnik::image_data_32,
|
||||
label_collision_detector4> raster_dispatch_type;
|
||||
typedef detail::markers_dispatch<cairo_context, mapnik::svg_storage_type, svg_attribute_type,
|
||||
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);
|
||||
std::string filename = get<std::string>(sym, keys::file, feature, "shape://ellipse");
|
||||
auto geom_transform = get_optional<transform_type>(sym, keys::geometry_transform);
|
||||
auto img_transform = get_optional<transform_type>(sym, keys::image_transform);
|
||||
auto width = get_optional<unsigned>(sym, keys::width);
|
||||
auto height = get_optional<unsigned>(sym, keys::height);
|
||||
bool clip = get<bool>(sym, keys::clip, feature, false);
|
||||
double smooth = get<double>(sym, keys::smooth, feature, 0.0);
|
||||
|
||||
context_.set_operator(comp_op);
|
||||
box2d<double> clip_box = common_.query_extent_;
|
||||
|
||||
agg::trans_affine tr = agg::trans_affine_scaling(common_.scale_factor_);
|
||||
|
||||
if (!filename.empty())
|
||||
{
|
||||
boost::optional<marker_ptr> mark = mapnik::marker_cache::instance().find(filename, true);
|
||||
if (mark && *mark)
|
||||
{
|
||||
agg::trans_affine geom_tr;
|
||||
if (geom_transform) { evaluate_transform(geom_tr, feature, *geom_transform); }
|
||||
box2d<double> const& bbox = (*mark)->bounding_box();
|
||||
setup_transform_scaling(tr, bbox.width(), bbox.height(), feature, sym);
|
||||
if (img_transform) { evaluate_transform(tr, feature, *img_transform); }
|
||||
|
||||
if ((*mark)->is_vector())
|
||||
{
|
||||
using namespace mapnik::svg;
|
||||
typedef agg::pod_bvector<path_attributes> svg_attributes_type;
|
||||
typedef detail::markers_dispatch<cairo_context, mapnik::svg_storage_type,
|
||||
svg_attributes_type,label_collision_detector4> dispatch_type;
|
||||
|
||||
boost::optional<svg_path_ptr> const& stock_vector_marker = (*mark)->get_vector_data();
|
||||
|
||||
// special case for simple ellipse markers
|
||||
// to allow for full control over rx/ry dimensions
|
||||
if (filename == "shape://ellipse"
|
||||
&& (width || height))
|
||||
{
|
||||
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);
|
||||
svg_attributes_type attributes;
|
||||
bool result = push_explicit_style( (*stock_vector_marker)->attributes(), attributes, sym);
|
||||
agg::trans_affine marker_tr = agg::trans_affine_scaling(common_.scale_factor_);
|
||||
if (img_transform) { evaluate_transform(marker_tr, feature, *img_transform); }
|
||||
box2d<double> new_bbox = marker_ellipse.bounding_box();
|
||||
|
||||
dispatch_type dispatch(context_, marker_ellipse, result?attributes:(*stock_vector_marker)->attributes(),
|
||||
*common_.detector_, sym, new_bbox, marker_tr, common_.scale_factor_);
|
||||
vertex_converter<box2d<double>, dispatch_type, markers_symbolizer,
|
||||
CoordTransform, proj_transform, agg::trans_affine, conv_types>
|
||||
converter(common_.query_extent_, dispatch, sym, common_.t_, prj_trans, marker_tr, common_.scale_factor_);
|
||||
|
||||
if (clip && feature.paths().size() > 0) // optional clip (default: true)
|
||||
{
|
||||
geometry_type::types type = feature.paths()[0].type();
|
||||
if (type == geometry_type::types::Polygon)
|
||||
converter.set<clip_poly_tag>();
|
||||
// line clipping disabled due to https://github.com/mapnik/mapnik/issues/1426
|
||||
//else if (type == geometry_type::types::LineString)
|
||||
// converter.template set<clip_line_tag>();
|
||||
// don't clip if type==geometry_type::types::Point
|
||||
}
|
||||
converter.set<transform_tag>(); //always transform
|
||||
if (smooth > 0.0) converter.set<smooth_tag>(); // optional smooth converter
|
||||
apply_markers_multi(feature, converter, sym);
|
||||
}
|
||||
else
|
||||
{
|
||||
svg_attributes_type attributes;
|
||||
bool result = push_explicit_style( (*stock_vector_marker)->attributes(), attributes, sym);
|
||||
|
||||
dispatch_type dispatch(context_, **stock_vector_marker, result?attributes:(*stock_vector_marker)->attributes(),
|
||||
*common_.detector_, sym, bbox, tr, common_.scale_factor_);
|
||||
vertex_converter<box2d<double>, dispatch_type, markers_symbolizer,
|
||||
CoordTransform, proj_transform, agg::trans_affine, conv_types>
|
||||
converter(common_.query_extent_, dispatch, sym, common_.t_, prj_trans, tr, common_.scale_factor_);
|
||||
|
||||
if (clip && feature.paths().size() > 0) // optional clip (default: true)
|
||||
{
|
||||
geometry_type::types type = feature.paths()[0].type();
|
||||
if (type == geometry_type::types::Polygon)
|
||||
converter.set<clip_poly_tag>();
|
||||
// line clipping disabled due to https://github.com/mapnik/mapnik/issues/1426
|
||||
//else if (type == geometry_type::types::LineString)
|
||||
// converter.template set<clip_line_tag>();
|
||||
// don't clip if type==geometry_type::types::Point
|
||||
}
|
||||
converter.set<transform_tag>(); //always transform
|
||||
if (smooth > 0.0) converter.set<smooth_tag>(); // optional smooth converter
|
||||
apply_markers_multi(feature, converter, sym);
|
||||
}
|
||||
}
|
||||
else // raster markers
|
||||
{
|
||||
typedef detail::markers_dispatch_2<cairo_context,
|
||||
mapnik::image_ptr,
|
||||
label_collision_detector4> dispatch_type;
|
||||
boost::optional<mapnik::image_ptr> marker = (*mark)->get_bitmap_data();
|
||||
if ( marker )
|
||||
{
|
||||
dispatch_type dispatch(context_, *marker,
|
||||
*common_.detector_, sym, bbox, tr, common_.scale_factor_);
|
||||
|
||||
vertex_converter<box2d<double>, dispatch_type, markers_symbolizer,
|
||||
CoordTransform, proj_transform, agg::trans_affine, conv_types>
|
||||
converter(common_.query_extent_, dispatch, sym, common_.t_, prj_trans, tr, common_.scale_factor_);
|
||||
|
||||
if (clip && feature.paths().size() > 0) // optional clip (default: true)
|
||||
{
|
||||
geometry_type::types type = feature.paths()[0].type();
|
||||
if (type == geometry_type::types::Polygon)
|
||||
converter.set<clip_poly_tag>();
|
||||
// line clipping disabled due to https://github.com/mapnik/mapnik/issues/1426
|
||||
//else if (type == geometry_type::types::LineString)
|
||||
// converter.template set<clip_line_tag>();
|
||||
// don't clip if type==geometry_type::types::Point
|
||||
}
|
||||
converter.set<transform_tag>(); //always transform
|
||||
if (smooth > 0.0) converter.set<smooth_tag>(); // optional smooth converter
|
||||
apply_markers_multi(feature, converter, sym);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
render_markers_symbolizer(
|
||||
sym, feature, prj_trans, common_, clip_box,
|
||||
[&](svg::svg_path_adapter &, svg_attribute_type const &attr, svg_storage_type &marker,
|
||||
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_);
|
||||
},
|
||||
[&](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_);
|
||||
});
|
||||
}
|
||||
|
||||
void cairo_renderer_base::process(text_symbolizer const& sym,
|
||||
|
|
|
@ -60,6 +60,7 @@ porting notes -->
|
|||
#include <mapnik/svg/svg_path_adapter.hpp>
|
||||
#include <mapnik/svg/svg_path_attributes.hpp>
|
||||
#include <mapnik/parse_path.hpp>
|
||||
#include <mapnik/renderer_common/process_markers_symbolizer.hpp>
|
||||
|
||||
// agg
|
||||
#include "agg_basics.h"
|
||||
|
@ -84,181 +85,66 @@ void grid_renderer<T>::process(markers_symbolizer const& sym,
|
|||
typedef typename grid_renderer_base_type::pixfmt_type pixfmt_type;
|
||||
typedef agg::renderer_scanline_bin_solid<grid_renderer_base_type> renderer_type;
|
||||
typedef label_collision_detector4 detector_type;
|
||||
typedef boost::mpl::vector<clip_poly_tag,transform_tag,smooth_tag> conv_types;
|
||||
|
||||
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);
|
||||
using namespace mapnik::svg;
|
||||
typedef agg::pod_bvector<path_attributes> svg_attribute_type;
|
||||
typedef svg_renderer_agg<svg_path_adapter,
|
||||
svg_attribute_type,
|
||||
renderer_type,
|
||||
pixfmt_type > svg_renderer_type;
|
||||
typedef vector_markers_rasterizer_dispatch_grid<buf_type,
|
||||
svg_renderer_type,
|
||||
grid_rasterizer,
|
||||
detector_type,
|
||||
mapnik::grid > vector_dispatch_type;
|
||||
typedef raster_markers_rasterizer_dispatch_grid<buf_type,
|
||||
grid_rasterizer,
|
||||
pixfmt_type,
|
||||
grid_renderer_base_type,
|
||||
renderer_type,
|
||||
detector_type,
|
||||
mapnik::grid > raster_dispatch_type;
|
||||
|
||||
if (!filename.empty())
|
||||
{
|
||||
boost::optional<marker_ptr> mark = mapnik::marker_cache::instance().find(filename, true);
|
||||
if (mark && *mark)
|
||||
{
|
||||
ras_ptr->reset();
|
||||
agg::trans_affine geom_tr;
|
||||
auto geom_transform = get_optional<transform_type>(sym, keys::geometry_transform);
|
||||
if (geom_transform) { evaluate_transform(geom_tr, feature, *geom_transform); }
|
||||
buf_type render_buf(pixmap_.raw_data(), common_.width_, common_.height_, common_.width_);
|
||||
ras_ptr->reset();
|
||||
box2d<double> clip_box = common_.query_extent_;
|
||||
|
||||
agg::trans_affine tr = agg::trans_affine_scaling(common_.scale_factor_*(1.0/pixmap_.get_resolution()));
|
||||
auto img_transform = get_optional<transform_type>(sym, keys::image_transform);
|
||||
|
||||
if ((*mark)->is_vector())
|
||||
{
|
||||
using namespace mapnik::svg;
|
||||
typedef agg::pod_bvector<path_attributes> svg_attribute_type;
|
||||
typedef svg_renderer_agg<svg_path_adapter,
|
||||
svg_attribute_type,
|
||||
renderer_type,
|
||||
pixfmt_type > svg_renderer_type;
|
||||
typedef vector_markers_rasterizer_dispatch_grid<buf_type,
|
||||
svg_renderer_type,
|
||||
grid_rasterizer,
|
||||
detector_type,
|
||||
mapnik::grid > dispatch_type;
|
||||
boost::optional<svg_path_ptr> const& stock_vector_marker = (*mark)->get_vector_data();
|
||||
|
||||
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
|
||||
// to allow for full control over rx/ry dimensions
|
||||
if (filename == "shape://ellipse"
|
||||
&& (width_expr || height_expr))
|
||||
{
|
||||
svg_storage_type marker_ellipse;
|
||||
vertex_stl_adapter<svg_path_storage> stl_storage(marker_ellipse.source());
|
||||
svg_path_adapter svg_path(stl_storage);
|
||||
// TODO - clamping to >= 4 pixels
|
||||
build_ellipse(sym, feature, marker_ellipse, svg_path);
|
||||
svg_attribute_type attributes;
|
||||
bool result = push_explicit_style( (*stock_vector_marker)->attributes(), attributes, sym);
|
||||
svg_renderer_type svg_renderer(svg_path, result ? attributes : (*stock_vector_marker)->attributes());
|
||||
if (img_transform) { evaluate_transform(tr, feature, *img_transform); }
|
||||
|
||||
box2d<double> bbox = marker_ellipse.bounding_box();
|
||||
coord2d center = bbox.center();
|
||||
agg::trans_affine_translation recenter(-center.x, -center.y);
|
||||
agg::trans_affine marker_trans = recenter * tr;
|
||||
buf_type render_buf(pixmap_.raw_data(), common_.width_, common_.height_, common_.width_);
|
||||
dispatch_type rasterizer_dispatch(render_buf,
|
||||
svg_renderer,
|
||||
*ras_ptr,
|
||||
bbox,
|
||||
marker_trans,
|
||||
sym,
|
||||
*common_.detector_,
|
||||
common_.scale_factor_,
|
||||
feature,
|
||||
pixmap_);
|
||||
vertex_converter<box2d<double>, dispatch_type, markers_symbolizer,
|
||||
CoordTransform, proj_transform, agg::trans_affine, conv_types>
|
||||
converter(common_.query_extent_, rasterizer_dispatch, sym,common_.t_,prj_trans,tr,common_.scale_factor_);
|
||||
if (clip && feature.paths().size() > 0) // optional clip (default: true)
|
||||
{
|
||||
geometry_type::types type = feature.paths()[0].type();
|
||||
if (type == geometry_type::types::Polygon)
|
||||
converter.template set<clip_poly_tag>();
|
||||
// line clipping disabled due to https://github.com/mapnik/mapnik/issues/1426
|
||||
//else if (type == LineString)
|
||||
// converter.template set<clip_line_tag>();
|
||||
// don't clip if type==Point
|
||||
}
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
box2d<double> const& bbox = (*mark)->bounding_box();
|
||||
setup_transform_scaling(tr, bbox.width(), bbox.height(), feature, sym);
|
||||
if (img_transform) { evaluate_transform(tr, feature, *img_transform); }
|
||||
|
||||
// TODO - clamping to >= 4 pixels
|
||||
coord2d center = bbox.center();
|
||||
agg::trans_affine_translation recenter(-center.x, -center.y);
|
||||
agg::trans_affine marker_trans = recenter * tr;
|
||||
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);
|
||||
svg_renderer_type svg_renderer(svg_path, result ? attributes : (*stock_vector_marker)->attributes());
|
||||
buf_type render_buf(pixmap_.raw_data(), common_.width_, common_.height_, common_.width_);
|
||||
dispatch_type rasterizer_dispatch(render_buf,
|
||||
svg_renderer,
|
||||
*ras_ptr,
|
||||
bbox,
|
||||
marker_trans,
|
||||
sym,
|
||||
*common_.detector_,
|
||||
common_.scale_factor_,
|
||||
feature,
|
||||
pixmap_);
|
||||
vertex_converter<box2d<double>, dispatch_type, markers_symbolizer,
|
||||
CoordTransform, proj_transform, agg::trans_affine, conv_types>
|
||||
converter(common_.query_extent_, rasterizer_dispatch, sym,common_.t_,prj_trans,tr,common_.scale_factor_);
|
||||
if (clip && feature.paths().size() > 0) // optional clip (default: true)
|
||||
{
|
||||
geometry_type::types type = feature.paths()[0].type();
|
||||
if (type == geometry_type::types::Polygon)
|
||||
converter.template set<clip_poly_tag>();
|
||||
// line clipping disabled due to https://github.com/mapnik/mapnik/issues/1426
|
||||
//else if (type == LineString)
|
||||
// converter.template set<clip_line_tag>();
|
||||
// don't clip if type==Point
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
else // raster markers
|
||||
{
|
||||
setup_transform_scaling(tr, (*mark)->width(), (*mark)->height(), feature, sym);
|
||||
if (img_transform) { evaluate_transform(tr, feature, *img_transform); }
|
||||
|
||||
box2d<double> const& bbox = (*mark)->bounding_box();
|
||||
// - clamp sizes to > 4 pixels of interactivity
|
||||
coord2d center = bbox.center();
|
||||
agg::trans_affine_translation recenter(-center.x, -center.y);
|
||||
agg::trans_affine marker_trans = recenter * tr;
|
||||
boost::optional<mapnik::image_ptr> marker = (*mark)->get_bitmap_data();
|
||||
typedef raster_markers_rasterizer_dispatch_grid<buf_type,
|
||||
grid_rasterizer,
|
||||
pixfmt_type,
|
||||
grid_renderer_base_type,
|
||||
renderer_type,
|
||||
detector_type,
|
||||
mapnik::grid > dispatch_type;
|
||||
buf_type render_buf(pixmap_.raw_data(), common_.width_, common_.height_, common_.width_);
|
||||
dispatch_type rasterizer_dispatch(render_buf,
|
||||
*ras_ptr,
|
||||
**marker,
|
||||
marker_trans,
|
||||
sym,
|
||||
*common_.detector_,
|
||||
common_.scale_factor_,
|
||||
feature,
|
||||
pixmap_);
|
||||
vertex_converter<box2d<double>, dispatch_type, markers_symbolizer,
|
||||
CoordTransform, proj_transform, agg::trans_affine, conv_types>
|
||||
converter(common_.query_extent_, rasterizer_dispatch, sym,common_.t_,prj_trans,tr,common_.scale_factor_);
|
||||
if (clip && feature.paths().size() > 0) // optional clip (default: true)
|
||||
{
|
||||
geometry_type::types type = feature.paths()[0].type();
|
||||
if (type == geometry_type::types::Polygon)
|
||||
converter.template set<clip_poly_tag>();
|
||||
// line clipping disabled due to https://github.com/mapnik/mapnik/issues/1426
|
||||
//else if (type == LineString)
|
||||
// converter.template set<clip_line_tag>();
|
||||
// don't clip if type==Point
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
render_markers_symbolizer(
|
||||
sym, feature, prj_trans, common_, clip_box,
|
||||
[&](svg_path_adapter &path, svg_attribute_type const &attr, svg_storage_type &,
|
||||
box2d<double> const &bbox, agg::trans_affine const &tr,
|
||||
bool) -> vector_dispatch_type {
|
||||
// TODO - clamping to >= 4 pixels
|
||||
coord2d center = bbox.center();
|
||||
agg::trans_affine_translation recenter(-center.x, -center.y);
|
||||
agg::trans_affine marker_trans = recenter * tr;
|
||||
return vector_dispatch_type(render_buf,
|
||||
path, attr,
|
||||
*ras_ptr,
|
||||
bbox,
|
||||
marker_trans,
|
||||
sym,
|
||||
*common_.detector_,
|
||||
common_.scale_factor_,
|
||||
feature,
|
||||
pixmap_);
|
||||
},
|
||||
[&](image_data_32 const &marker, agg::trans_affine const &tr,
|
||||
box2d<double> const &bbox) -> raster_dispatch_type {
|
||||
// - clamp sizes to > 4 pixels of interactivity
|
||||
coord2d center = bbox.center();
|
||||
agg::trans_affine_translation recenter(-center.x, -center.y);
|
||||
agg::trans_affine marker_trans = recenter * tr;
|
||||
return raster_dispatch_type(render_buf,
|
||||
*ras_ptr,
|
||||
marker,
|
||||
marker_trans,
|
||||
sym,
|
||||
*common_.detector_,
|
||||
common_.scale_factor_,
|
||||
feature,
|
||||
pixmap_);
|
||||
});
|
||||
}
|
||||
|
||||
template void grid_renderer<grid>::process(markers_symbolizer const&,
|
||||
|
|
Loading…
Reference in a new issue