Refactor markers dispatchers to use a common base class to share code.
This commit is contained in:
parent
c5d0c44de0
commit
1b15e53b63
12 changed files with 536 additions and 545 deletions
148
include/mapnik/agg_render_marker.hpp
Normal file
148
include/mapnik/agg_render_marker.hpp
Normal file
|
@ -0,0 +1,148 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2014 Artem Pavlenko
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <mapnik/color.hpp>
|
||||||
|
#include <mapnik/feature.hpp>
|
||||||
|
#include <mapnik/geometry.hpp>
|
||||||
|
#include <mapnik/geom_util.hpp>
|
||||||
|
#include <mapnik/svg/svg_path_attributes.hpp>
|
||||||
|
#include <mapnik/svg/svg_converter.hpp>
|
||||||
|
#include <mapnik/vertex_converters.hpp>
|
||||||
|
#include <mapnik/box2d.hpp>
|
||||||
|
|
||||||
|
// agg
|
||||||
|
#include "agg_color_rgba.h"
|
||||||
|
#include "agg_renderer_base.h"
|
||||||
|
#include "agg_renderer_scanline.h"
|
||||||
|
#include "agg_rendering_buffer.h"
|
||||||
|
#include "agg_scanline_u.h"
|
||||||
|
#include "agg_image_filters.h"
|
||||||
|
#include "agg_trans_affine.h"
|
||||||
|
#include "agg_span_allocator.h"
|
||||||
|
#include "agg_image_accessors.h"
|
||||||
|
#include "agg_pixfmt_rgba.h"
|
||||||
|
#include "agg_span_image_filter_rgba.h"
|
||||||
|
#include "agg_span_interpolator_linear.h"
|
||||||
|
|
||||||
|
namespace mapnik {
|
||||||
|
|
||||||
|
template <typename SvgRenderer, typename RasterizerType, typename RendererBaseType>
|
||||||
|
void render_vector_marker(SvgRenderer & svg_renderer, RasterizerType & ras, RendererBaseType & renb,
|
||||||
|
box2d<double> const& bbox, agg::trans_affine const& tr,
|
||||||
|
double opacity, bool snap_to_pixels)
|
||||||
|
{
|
||||||
|
agg::scanline_u8 sl;
|
||||||
|
if (snap_to_pixels)
|
||||||
|
{
|
||||||
|
// https://github.com/mapnik/mapnik/issues/1316
|
||||||
|
agg::trans_affine snap_tr = tr;
|
||||||
|
snap_tr.tx = std::floor(snap_tr.tx + .5);
|
||||||
|
snap_tr.ty = std::floor(snap_tr.ty + .5);
|
||||||
|
svg_renderer.render(ras, sl, renb, snap_tr, opacity, bbox);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
svg_renderer.render(ras, sl, renb, tr, opacity, bbox);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename RendererType, typename RasterizerType>
|
||||||
|
void render_raster_marker(RendererType renb, RasterizerType & ras, image_data_32 & src,
|
||||||
|
agg::trans_affine const& tr, double opacity,
|
||||||
|
float scale_factor, bool snap_to_pixels)
|
||||||
|
{
|
||||||
|
using color_type = agg::rgba8;
|
||||||
|
using pixfmt_pre = agg::pixfmt_rgba32_pre;
|
||||||
|
agg::scanline_u8 sl;
|
||||||
|
double width = src.width();
|
||||||
|
double height = src.height();
|
||||||
|
if (std::fabs(1.0 - scale_factor) < 0.001
|
||||||
|
&& (std::fabs(1.0 - tr.sx) < agg::affine_epsilon)
|
||||||
|
&& (std::fabs(0.0 - tr.shy) < agg::affine_epsilon)
|
||||||
|
&& (std::fabs(0.0 - tr.shx) < agg::affine_epsilon)
|
||||||
|
&& (std::fabs(1.0 - tr.sy) < agg::affine_epsilon))
|
||||||
|
{
|
||||||
|
agg::rendering_buffer src_buffer((unsigned char *)src.getBytes(),src.width(),src.height(),src.width() * 4);
|
||||||
|
pixfmt_pre pixf_mask(src_buffer);
|
||||||
|
if (snap_to_pixels)
|
||||||
|
{
|
||||||
|
renb.blend_from(pixf_mask,
|
||||||
|
0,
|
||||||
|
std::floor(tr.tx + .5),
|
||||||
|
std::floor(tr.ty + .5),
|
||||||
|
unsigned(255*opacity));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
renb.blend_from(pixf_mask,
|
||||||
|
0,
|
||||||
|
tr.tx,
|
||||||
|
tr.ty,
|
||||||
|
unsigned(255*opacity));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
using img_accessor_type = agg::image_accessor_clone<pixfmt_pre>;
|
||||||
|
using interpolator_type = agg::span_interpolator_linear<>;
|
||||||
|
//using span_gen_type = agg::span_image_filter_rgba_2x2<img_accessor_type,interpolator_type>;
|
||||||
|
using span_gen_type = agg::span_image_resample_rgba_affine<img_accessor_type>;
|
||||||
|
using renderer_type = agg::renderer_scanline_aa_alpha<RendererType,
|
||||||
|
agg::span_allocator<color_type>,
|
||||||
|
span_gen_type>;
|
||||||
|
|
||||||
|
double p[8];
|
||||||
|
p[0] = 0; p[1] = 0;
|
||||||
|
p[2] = width; p[3] = 0;
|
||||||
|
p[4] = width; p[5] = height;
|
||||||
|
p[6] = 0; p[7] = height;
|
||||||
|
tr.transform(&p[0], &p[1]);
|
||||||
|
tr.transform(&p[2], &p[3]);
|
||||||
|
tr.transform(&p[4], &p[5]);
|
||||||
|
tr.transform(&p[6], &p[7]);
|
||||||
|
agg::span_allocator<color_type> sa;
|
||||||
|
agg::image_filter_lut filter;
|
||||||
|
filter.calculate(agg::image_filter_bilinear(), true);
|
||||||
|
agg::rendering_buffer marker_buf((unsigned char *)src.getBytes(),
|
||||||
|
src.width(),
|
||||||
|
src.height(),
|
||||||
|
src.width()*4);
|
||||||
|
pixfmt_pre pixf(marker_buf);
|
||||||
|
img_accessor_type ia(pixf);
|
||||||
|
agg::trans_affine final_tr(p, 0, 0, width, height);
|
||||||
|
if (snap_to_pixels)
|
||||||
|
{
|
||||||
|
final_tr.tx = std::floor(final_tr.tx+.5);
|
||||||
|
final_tr.ty = std::floor(final_tr.ty+.5);
|
||||||
|
}
|
||||||
|
interpolator_type interpolator(final_tr);
|
||||||
|
span_gen_type sg(ia, interpolator, filter);
|
||||||
|
renderer_type rp(renb, sa, sg, unsigned(opacity*255));
|
||||||
|
ras.move_to_d(p[0],p[1]);
|
||||||
|
ras.line_to_d(p[2],p[3]);
|
||||||
|
ras.line_to_d(p[4],p[5]);
|
||||||
|
ras.line_to_d(p[6],p[7]);
|
||||||
|
agg::render_scanlines(ras, sl, rp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -37,10 +37,10 @@ struct pixel_position;
|
||||||
template <typename T> class box2d;
|
template <typename T> class box2d;
|
||||||
namespace svg { struct path_attributes; }
|
namespace svg { struct path_attributes; }
|
||||||
|
|
||||||
void render_vector_marker(cairo_context & context, pixel_position const& pos,
|
void render_vector_marker(cairo_context & context, svg::svg_path_adapter & svg_path,
|
||||||
svg::svg_path_adapter & svg_path, box2d<double> const& bbox,
|
|
||||||
agg::pod_bvector<svg::path_attributes> const & attributes,
|
agg::pod_bvector<svg::path_attributes> const & attributes,
|
||||||
agg::trans_affine const& tr, double opacity, bool recenter);
|
box2d<double> const& bbox, agg::trans_affine const& tr,
|
||||||
|
double opacity);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,174 +0,0 @@
|
||||||
/*****************************************************************************
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef MAPNIK_GRID_MARKER_HELPERS_HPP
|
|
||||||
#define MAPNIK_GRID_MARKER_HELPERS_HPP
|
|
||||||
|
|
||||||
// mapnik
|
|
||||||
#include <mapnik/symbolizer.hpp>
|
|
||||||
#include <mapnik/markers_placement.hpp>
|
|
||||||
#include <mapnik/marker_helpers.hpp>
|
|
||||||
#include <mapnik/geometry.hpp>
|
|
||||||
#include <mapnik/geom_util.hpp>
|
|
||||||
|
|
||||||
// agg
|
|
||||||
#include "agg_renderer_scanline.h"
|
|
||||||
#include "agg_scanline_bin.h"
|
|
||||||
#include "agg_image_filters.h"
|
|
||||||
#include "agg_trans_bilinear.h"
|
|
||||||
#include "agg_span_allocator.h"
|
|
||||||
#include "agg_image_accessors.h"
|
|
||||||
#include "agg_span_image_filter_gray.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace mapnik {
|
|
||||||
|
|
||||||
template <typename RendererBase, typename RendererType, typename Detector, typename RendererContext>
|
|
||||||
struct raster_markers_rasterizer_dispatch_grid : public raster_markers_dispatch<Detector>
|
|
||||||
{
|
|
||||||
using pixfmt_type = typename RendererBase::pixfmt_type;
|
|
||||||
using color_type = typename RendererBase::pixfmt_type::color_type;
|
|
||||||
|
|
||||||
using BufferType = typename std::tuple_element<0,RendererContext>::type;
|
|
||||||
using RasterizerType = typename std::tuple_element<1,RendererContext>::type;
|
|
||||||
using PixMapType = typename std::tuple_element<2,RendererContext>::type;
|
|
||||||
|
|
||||||
raster_markers_rasterizer_dispatch_grid(image_data_32 const& src,
|
|
||||||
agg::trans_affine const& marker_trans,
|
|
||||||
markers_symbolizer const& sym,
|
|
||||||
Detector & detector,
|
|
||||||
double scale_factor,
|
|
||||||
mapnik::feature_impl & feature,
|
|
||||||
attributes const& vars,
|
|
||||||
RendererContext const& renderer_context)
|
|
||||||
: raster_markers_dispatch<Detector>(src, marker_trans, sym, detector, scale_factor,
|
|
||||||
feature, vars, false),
|
|
||||||
buf_(std::get<0>(renderer_context)),
|
|
||||||
pixf_(buf_),
|
|
||||||
renb_(pixf_),
|
|
||||||
ras_(std::get<1>(renderer_context)),
|
|
||||||
pixmap_(std::get<2>(renderer_context)),
|
|
||||||
placed_(false)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void render_raster_marker(agg::trans_affine const& marker_tr, double opacity)
|
|
||||||
{
|
|
||||||
agg::scanline_bin sl_;
|
|
||||||
double width = src_.width();
|
|
||||||
double height = src_.height();
|
|
||||||
double p[8];
|
|
||||||
p[0] = 0; p[1] = 0;
|
|
||||||
p[2] = width; p[3] = 0;
|
|
||||||
p[4] = width; p[5] = height;
|
|
||||||
p[6] = 0; p[7] = height;
|
|
||||||
marker_tr.transform(&p[0], &p[1]);
|
|
||||||
marker_tr.transform(&p[2], &p[3]);
|
|
||||||
marker_tr.transform(&p[4], &p[5]);
|
|
||||||
marker_tr.transform(&p[6], &p[7]);
|
|
||||||
ras_.move_to_d(p[0],p[1]);
|
|
||||||
ras_.line_to_d(p[2],p[3]);
|
|
||||||
ras_.line_to_d(p[4],p[5]);
|
|
||||||
ras_.line_to_d(p[6],p[7]);
|
|
||||||
RendererType ren(renb_);
|
|
||||||
ren.color(color_type(feature_.id()));
|
|
||||||
agg::render_scanlines(ras_, sl_, ren);
|
|
||||||
if (!placed_)
|
|
||||||
{
|
|
||||||
pixmap_.add_feature(feature_);
|
|
||||||
placed_ = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
BufferType & buf_;
|
|
||||||
pixfmt_type pixf_;
|
|
||||||
RendererBase renb_;
|
|
||||||
RasterizerType & ras_;
|
|
||||||
PixMapType & pixmap_;
|
|
||||||
bool placed_;
|
|
||||||
|
|
||||||
using raster_markers_dispatch<Detector>::src_;
|
|
||||||
using raster_markers_dispatch<Detector>::feature_;
|
|
||||||
using raster_markers_dispatch<Detector>::snap_to_pixels_;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <typename SvgRenderer, typename Detector, typename RendererContext>
|
|
||||||
struct vector_markers_rasterizer_dispatch_grid : public vector_markers_dispatch<Detector>
|
|
||||||
{
|
|
||||||
using renderer_base = typename SvgRenderer::renderer_base ;
|
|
||||||
using vertex_source_type = typename SvgRenderer::vertex_source_type ;
|
|
||||||
using attribute_source_type = typename SvgRenderer::attribute_source_type;
|
|
||||||
using pixfmt_type = typename renderer_base::pixfmt_type ;
|
|
||||||
|
|
||||||
using BufferType = typename std::tuple_element<0,RendererContext>::type;
|
|
||||||
using RasterizerType = typename std::tuple_element<1,RendererContext>::type;
|
|
||||||
using PixMapType = typename std::tuple_element<2,RendererContext>::type;
|
|
||||||
|
|
||||||
vector_markers_rasterizer_dispatch_grid(vertex_source_type & path,
|
|
||||||
attribute_source_type const& attrs,
|
|
||||||
box2d<double> const& bbox,
|
|
||||||
agg::trans_affine const& marker_trans,
|
|
||||||
markers_symbolizer const& sym,
|
|
||||||
Detector & detector,
|
|
||||||
double scale_factor,
|
|
||||||
mapnik::feature_impl & feature,
|
|
||||||
attributes const& vars,
|
|
||||||
bool snap_to_pixels,
|
|
||||||
RendererContext const& renderer_context)
|
|
||||||
: vector_markers_dispatch<Detector>(bbox, marker_trans, sym, detector, scale_factor, feature, vars, snap_to_pixels),
|
|
||||||
buf_(std::get<0>(renderer_context)),
|
|
||||||
pixf_(buf_),
|
|
||||||
renb_(pixf_),
|
|
||||||
svg_renderer_(path, attrs),
|
|
||||||
ras_(std::get<1>(renderer_context)),
|
|
||||||
pixmap_(std::get<2>(renderer_context)),
|
|
||||||
placed_(false)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void render_vector_marker(agg::trans_affine & marker_tr, double opacity)
|
|
||||||
{
|
|
||||||
agg::scanline_bin sl_;
|
|
||||||
svg_renderer_.render_id(ras_, sl_, renb_, feature_.id(), marker_tr, opacity, bbox_);
|
|
||||||
if (!placed_)
|
|
||||||
{
|
|
||||||
pixmap_.add_feature(feature_);
|
|
||||||
placed_ = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
BufferType & buf_;
|
|
||||||
pixfmt_type pixf_;
|
|
||||||
renderer_base renb_;
|
|
||||||
SvgRenderer svg_renderer_;
|
|
||||||
RasterizerType & ras_;
|
|
||||||
PixMapType & pixmap_;
|
|
||||||
bool placed_;
|
|
||||||
|
|
||||||
using vector_markers_dispatch<Detector>::bbox_;
|
|
||||||
using vector_markers_dispatch<Detector>::feature_;
|
|
||||||
using vector_markers_dispatch<Detector>::snap_to_pixels_;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
72
include/mapnik/grid/grid_render_marker.hpp
Normal file
72
include/mapnik/grid/grid_render_marker.hpp
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef MAPNIK_GRID_MARKER_HELPERS_HPP
|
||||||
|
#define MAPNIK_GRID_MARKER_HELPERS_HPP
|
||||||
|
|
||||||
|
// mapnik
|
||||||
|
#include <mapnik/feature.hpp>
|
||||||
|
|
||||||
|
// agg
|
||||||
|
#include "agg_renderer_scanline.h"
|
||||||
|
#include "agg_scanline_bin.h"
|
||||||
|
#include "agg_image_filters.h"
|
||||||
|
#include "agg_trans_bilinear.h"
|
||||||
|
#include "agg_span_allocator.h"
|
||||||
|
#include "agg_image_accessors.h"
|
||||||
|
#include "agg_span_image_filter_gray.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace mapnik {
|
||||||
|
|
||||||
|
template <typename RendererType, typename RasterizerType>
|
||||||
|
void render_raster_marker(RendererType ren,
|
||||||
|
RasterizerType & ras,
|
||||||
|
image_data_32 & src,
|
||||||
|
mapnik::feature_impl const& feature,
|
||||||
|
agg::trans_affine const& marker_tr,
|
||||||
|
double opacity)
|
||||||
|
{
|
||||||
|
using color_type = typename RendererType::color_type;
|
||||||
|
agg::scanline_bin sl;
|
||||||
|
double width = src.width();
|
||||||
|
double height = src.height();
|
||||||
|
double p[8];
|
||||||
|
p[0] = 0; p[1] = 0;
|
||||||
|
p[2] = width; p[3] = 0;
|
||||||
|
p[4] = width; p[5] = height;
|
||||||
|
p[6] = 0; p[7] = height;
|
||||||
|
marker_tr.transform(&p[0], &p[1]);
|
||||||
|
marker_tr.transform(&p[2], &p[3]);
|
||||||
|
marker_tr.transform(&p[4], &p[5]);
|
||||||
|
marker_tr.transform(&p[6], &p[7]);
|
||||||
|
ras.move_to_d(p[0],p[1]);
|
||||||
|
ras.line_to_d(p[2],p[3]);
|
||||||
|
ras.line_to_d(p[4],p[5]);
|
||||||
|
ras.line_to_d(p[6],p[7]);
|
||||||
|
ren.color(color_type(feature.id()));
|
||||||
|
agg::render_scanlines(ras, sl, ren);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -40,19 +40,7 @@
|
||||||
#include <mapnik/label_collision_detector.hpp>
|
#include <mapnik/label_collision_detector.hpp>
|
||||||
|
|
||||||
// agg
|
// agg
|
||||||
#include "agg_ellipse.h"
|
|
||||||
#include "agg_color_rgba.h"
|
|
||||||
#include "agg_renderer_base.h"
|
|
||||||
#include "agg_renderer_scanline.h"
|
|
||||||
#include "agg_rendering_buffer.h"
|
|
||||||
#include "agg_scanline_u.h"
|
|
||||||
#include "agg_image_filters.h"
|
|
||||||
#include "agg_trans_affine.h"
|
#include "agg_trans_affine.h"
|
||||||
#include "agg_span_allocator.h"
|
|
||||||
#include "agg_image_accessors.h"
|
|
||||||
#include "agg_pixfmt_rgba.h"
|
|
||||||
#include "agg_span_image_filter_rgba.h"
|
|
||||||
#include "agg_span_interpolator_linear.h"
|
|
||||||
|
|
||||||
// boost
|
// boost
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
|
@ -71,22 +59,20 @@ using svg_attribute_type = agg::pod_bvector<svg::path_attributes>;
|
||||||
template <typename Detector>
|
template <typename Detector>
|
||||||
struct vector_markers_dispatch : mapnik::noncopyable
|
struct vector_markers_dispatch : mapnik::noncopyable
|
||||||
{
|
{
|
||||||
vector_markers_dispatch(box2d<double> const& bbox,
|
vector_markers_dispatch(svg_path_ptr const& src,
|
||||||
agg::trans_affine const& marker_trans,
|
agg::trans_affine const& marker_trans,
|
||||||
symbolizer_base const& sym,
|
symbolizer_base const& sym,
|
||||||
Detector & detector,
|
Detector & detector,
|
||||||
double scale_factor,
|
double scale_factor,
|
||||||
feature_impl & feature,
|
feature_impl & feature,
|
||||||
attributes const& vars,
|
attributes const& vars)
|
||||||
bool snap_to_pixels)
|
: src_(src),
|
||||||
: bbox_(bbox),
|
|
||||||
marker_trans_(marker_trans),
|
marker_trans_(marker_trans),
|
||||||
sym_(sym),
|
sym_(sym),
|
||||||
detector_(detector),
|
detector_(detector),
|
||||||
feature_(feature),
|
feature_(feature),
|
||||||
vars_(vars),
|
vars_(vars),
|
||||||
scale_factor_(scale_factor),
|
scale_factor_(scale_factor)
|
||||||
snap_to_pixels_(snap_to_pixels)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual ~vector_markers_dispatch() {}
|
virtual ~vector_markers_dispatch() {}
|
||||||
|
@ -101,10 +87,11 @@ struct vector_markers_dispatch : mapnik::noncopyable
|
||||||
double opacity = get<double>(sym_,keys::opacity, feature_, vars_, 1.0);
|
double opacity = get<double>(sym_,keys::opacity, feature_, vars_, 1.0);
|
||||||
double spacing = get<double>(sym_, keys::spacing, feature_, vars_, 100.0);
|
double spacing = get<double>(sym_, keys::spacing, feature_, vars_, 100.0);
|
||||||
double max_error = get<double>(sym_, keys::max_error, feature_, vars_, 0.2);
|
double max_error = get<double>(sym_, keys::max_error, feature_, vars_, 0.2);
|
||||||
coord2d center = bbox_.center();
|
box2d<double> const& bbox = src_->bounding_box();
|
||||||
|
coord2d center = bbox.center();
|
||||||
agg::trans_affine_translation recenter(-center.x, -center.y);
|
agg::trans_affine_translation recenter(-center.x, -center.y);
|
||||||
agg::trans_affine tr = recenter * marker_trans_;
|
agg::trans_affine tr = recenter * marker_trans_;
|
||||||
markers_placement_params params { bbox_, tr, spacing * scale_factor_, max_error, allow_overlap, avoid_edges };
|
markers_placement_params params { bbox, tr, spacing * scale_factor_, max_error, allow_overlap, avoid_edges };
|
||||||
markers_placement_finder<T, Detector> placement_finder(
|
markers_placement_finder<T, Detector> placement_finder(
|
||||||
placement_method, path, detector_, params);
|
placement_method, path, detector_, params);
|
||||||
double x, y, angle = .0;
|
double x, y, angle = .0;
|
||||||
|
@ -113,42 +100,39 @@ struct vector_markers_dispatch : mapnik::noncopyable
|
||||||
agg::trans_affine matrix = tr;
|
agg::trans_affine matrix = tr;
|
||||||
matrix.rotate(angle);
|
matrix.rotate(angle);
|
||||||
matrix.translate(x, y);
|
matrix.translate(x, y);
|
||||||
render_vector_marker(matrix, opacity);
|
render_marker(matrix, opacity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void render_vector_marker(agg::trans_affine & marker_tr, double opacity) = 0;
|
virtual void render_marker(agg::trans_affine const& marker_tr, double opacity) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
box2d<double> const& bbox_;
|
svg_path_ptr const& src_;
|
||||||
agg::trans_affine const& marker_trans_;
|
agg::trans_affine const& marker_trans_;
|
||||||
symbolizer_base const& sym_;
|
symbolizer_base const& sym_;
|
||||||
Detector & detector_;
|
Detector & detector_;
|
||||||
feature_impl & feature_;
|
feature_impl & feature_;
|
||||||
attributes const& vars_;
|
attributes const& vars_;
|
||||||
double scale_factor_;
|
double scale_factor_;
|
||||||
bool snap_to_pixels_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Detector>
|
template <typename Detector>
|
||||||
struct raster_markers_dispatch : mapnik::noncopyable
|
struct raster_markers_dispatch : mapnik::noncopyable
|
||||||
{
|
{
|
||||||
raster_markers_dispatch(image_data_32 const& src,
|
raster_markers_dispatch(image_data_32 & src,
|
||||||
agg::trans_affine const& marker_trans,
|
agg::trans_affine const& marker_trans,
|
||||||
symbolizer_base const& sym,
|
symbolizer_base const& sym,
|
||||||
Detector & detector,
|
Detector & detector,
|
||||||
double scale_factor,
|
double scale_factor,
|
||||||
feature_impl & feature,
|
feature_impl & feature,
|
||||||
attributes const& vars,
|
attributes const& vars)
|
||||||
bool snap_to_pixels = false)
|
|
||||||
: src_(src),
|
: src_(src),
|
||||||
marker_trans_(marker_trans),
|
marker_trans_(marker_trans),
|
||||||
sym_(sym),
|
sym_(sym),
|
||||||
detector_(detector),
|
detector_(detector),
|
||||||
feature_(feature),
|
feature_(feature),
|
||||||
vars_(vars),
|
vars_(vars),
|
||||||
scale_factor_(scale_factor),
|
scale_factor_(scale_factor)
|
||||||
snap_to_pixels_(snap_to_pixels)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual ~raster_markers_dispatch() {}
|
virtual ~raster_markers_dispatch() {}
|
||||||
|
@ -159,11 +143,11 @@ struct raster_markers_dispatch : mapnik::noncopyable
|
||||||
marker_placement_enum placement_method = get<marker_placement_enum>(sym_, keys::markers_placement_type, feature_, vars_, MARKER_POINT_PLACEMENT);
|
marker_placement_enum placement_method = get<marker_placement_enum>(sym_, keys::markers_placement_type, feature_, vars_, MARKER_POINT_PLACEMENT);
|
||||||
bool allow_overlap = get<bool>(sym_, keys::allow_overlap, feature_, vars_, false);
|
bool allow_overlap = get<bool>(sym_, keys::allow_overlap, feature_, vars_, false);
|
||||||
bool avoid_edges = get<bool>(sym_, keys::avoid_edges, feature_, vars_, false);
|
bool avoid_edges = get<bool>(sym_, keys::avoid_edges, feature_, vars_, false);
|
||||||
box2d<double> bbox(0,0, src_.width(), src_.height());
|
|
||||||
double opacity = get<double>(sym_, keys::opacity, feature_, vars_, 1.0);
|
double opacity = get<double>(sym_, keys::opacity, feature_, vars_, 1.0);
|
||||||
bool ignore_placement = get<bool>(sym_, keys::ignore_placement, feature_, vars_, false);
|
bool ignore_placement = get<bool>(sym_, keys::ignore_placement, feature_, vars_, false);
|
||||||
double spacing = get<double>(sym_, keys::spacing, feature_, vars_, 100.0);
|
double spacing = get<double>(sym_, keys::spacing, feature_, vars_, 100.0);
|
||||||
double max_error = get<double>(sym_, keys::max_error, feature_, vars_, 0.2);
|
double max_error = get<double>(sym_, keys::max_error, feature_, vars_, 0.2);
|
||||||
|
box2d<double> bbox(0,0, src_.width(), src_.height());
|
||||||
markers_placement_params params { bbox, marker_trans_, spacing * scale_factor_, max_error, allow_overlap, avoid_edges };
|
markers_placement_params params { bbox, marker_trans_, spacing * scale_factor_, max_error, allow_overlap, avoid_edges };
|
||||||
markers_placement_finder<T, label_collision_detector4> placement_finder(
|
markers_placement_finder<T, label_collision_detector4> placement_finder(
|
||||||
placement_method, path, detector_, params);
|
placement_method, path, detector_, params);
|
||||||
|
@ -173,199 +157,20 @@ struct raster_markers_dispatch : mapnik::noncopyable
|
||||||
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);
|
||||||
render_raster_marker(matrix, opacity);
|
render_marker(matrix, opacity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void render_raster_marker(agg::trans_affine const& marker_tr, double opacity) = 0;
|
virtual void render_marker(agg::trans_affine const& marker_tr, double opacity) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
image_data_32 const& src_;
|
image_data_32 & src_;
|
||||||
agg::trans_affine const& marker_trans_;
|
agg::trans_affine const& marker_trans_;
|
||||||
symbolizer_base const& sym_;
|
symbolizer_base const& sym_;
|
||||||
Detector & detector_;
|
Detector & detector_;
|
||||||
feature_impl & feature_;
|
feature_impl & feature_;
|
||||||
attributes const& vars_;
|
attributes const& vars_;
|
||||||
double scale_factor_;
|
double scale_factor_;
|
||||||
bool snap_to_pixels_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename SvgRenderer, typename Detector, typename RendererContext>
|
|
||||||
struct vector_markers_rasterizer_dispatch_agg : public vector_markers_dispatch<Detector>
|
|
||||||
{
|
|
||||||
using renderer_base = typename SvgRenderer::renderer_base ;
|
|
||||||
using vertex_source_type = typename SvgRenderer::vertex_source_type ;
|
|
||||||
using attribute_source_type = typename SvgRenderer::attribute_source_type;
|
|
||||||
using pixfmt_type = typename renderer_base::pixfmt_type ;
|
|
||||||
|
|
||||||
using BufferType = typename std::tuple_element<0,RendererContext>::type;
|
|
||||||
using RasterizerType = typename std::tuple_element<1,RendererContext>::type;
|
|
||||||
|
|
||||||
vector_markers_rasterizer_dispatch_agg(vertex_source_type & path,
|
|
||||||
attribute_source_type const& attrs,
|
|
||||||
box2d<double> const& bbox,
|
|
||||||
agg::trans_affine const& marker_trans,
|
|
||||||
symbolizer_base const& sym,
|
|
||||||
Detector & detector,
|
|
||||||
double scale_factor,
|
|
||||||
feature_impl & feature,
|
|
||||||
attributes const& vars,
|
|
||||||
bool snap_to_pixels,
|
|
||||||
RendererContext const& renderer_context)
|
|
||||||
: vector_markers_dispatch<Detector>(bbox, marker_trans, sym, detector, scale_factor, feature, vars, snap_to_pixels),
|
|
||||||
buf_(std::get<0>(renderer_context)),
|
|
||||||
pixf_(buf_),
|
|
||||||
renb_(pixf_),
|
|
||||||
svg_renderer_(path, attrs),
|
|
||||||
ras_(std::get<1>(renderer_context))
|
|
||||||
{
|
|
||||||
pixf_.comp_op(static_cast<agg::comp_op_e>(get<composite_mode_e>(sym, keys::comp_op, feature, vars, src_over)));
|
|
||||||
}
|
|
||||||
|
|
||||||
~vector_markers_rasterizer_dispatch_agg() {}
|
|
||||||
|
|
||||||
void render_vector_marker(agg::trans_affine & marker_tr, double opacity)
|
|
||||||
{
|
|
||||||
agg::scanline_u8 sl_;
|
|
||||||
|
|
||||||
if (snap_to_pixels_)
|
|
||||||
{
|
|
||||||
// https://github.com/mapnik/mapnik/issues/1316
|
|
||||||
marker_tr.tx = std::floor(marker_tr.tx + .5);
|
|
||||||
marker_tr.ty = std::floor(marker_tr.ty + .5);
|
|
||||||
}
|
|
||||||
svg_renderer_.render(ras_, sl_, renb_, marker_tr, opacity, bbox_);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
BufferType & buf_;
|
|
||||||
pixfmt_type pixf_;
|
|
||||||
renderer_base renb_;
|
|
||||||
SvgRenderer svg_renderer_;
|
|
||||||
RasterizerType & ras_;
|
|
||||||
|
|
||||||
using vector_markers_dispatch<Detector>::bbox_;
|
|
||||||
using vector_markers_dispatch<Detector>::snap_to_pixels_;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Detector, typename RendererContext>
|
|
||||||
struct raster_markers_rasterizer_dispatch_agg : public raster_markers_dispatch<Detector>
|
|
||||||
{
|
|
||||||
using BufferType = typename std::remove_reference<typename std::tuple_element<0,RendererContext>::type>::type;
|
|
||||||
using RasterizerType = typename std::tuple_element<1,RendererContext>::type;
|
|
||||||
|
|
||||||
using color_type = agg::rgba8;
|
|
||||||
using order_type = agg::order_rgba;
|
|
||||||
using pixel_type = agg::pixel32_type;
|
|
||||||
using blender_type = agg::comp_op_adaptor_rgba_pre<color_type, order_type>; // comp blender
|
|
||||||
using pixfmt_comp_type = agg::pixfmt_custom_blend_rgba<blender_type, BufferType>;
|
|
||||||
using renderer_base = agg::renderer_base<pixfmt_comp_type>;
|
|
||||||
|
|
||||||
raster_markers_rasterizer_dispatch_agg(image_data_32 const& src,
|
|
||||||
agg::trans_affine const& marker_trans,
|
|
||||||
symbolizer_base const& sym,
|
|
||||||
Detector & detector,
|
|
||||||
double scale_factor,
|
|
||||||
feature_impl & feature,
|
|
||||||
attributes const& vars,
|
|
||||||
RendererContext const& renderer_context,
|
|
||||||
bool snap_to_pixels = false)
|
|
||||||
: raster_markers_dispatch<Detector>(src, marker_trans, sym, detector, scale_factor,
|
|
||||||
feature, vars, snap_to_pixels),
|
|
||||||
buf_(std::get<0>(renderer_context)),
|
|
||||||
pixf_(buf_),
|
|
||||||
renb_(pixf_),
|
|
||||||
ras_(std::get<1>(renderer_context))
|
|
||||||
{
|
|
||||||
pixf_.comp_op(static_cast<agg::comp_op_e>(get<composite_mode_e>(sym, keys::comp_op, feature, vars, src_over)));
|
|
||||||
}
|
|
||||||
|
|
||||||
~raster_markers_rasterizer_dispatch_agg() {}
|
|
||||||
|
|
||||||
void render_raster_marker(agg::trans_affine const& marker_tr, double opacity)
|
|
||||||
{
|
|
||||||
using pixfmt_pre = agg::pixfmt_rgba32_pre;
|
|
||||||
agg::scanline_u8 sl_;
|
|
||||||
double width = this->src_.width();
|
|
||||||
double height = this->src_.height();
|
|
||||||
if (std::fabs(1.0 - this->scale_factor_) < 0.001
|
|
||||||
&& (std::fabs(1.0 - marker_tr.sx) < agg::affine_epsilon)
|
|
||||||
&& (std::fabs(0.0 - marker_tr.shy) < agg::affine_epsilon)
|
|
||||||
&& (std::fabs(0.0 - marker_tr.shx) < agg::affine_epsilon)
|
|
||||||
&& (std::fabs(1.0 - marker_tr.sy) < agg::affine_epsilon))
|
|
||||||
{
|
|
||||||
agg::rendering_buffer src_buffer((unsigned char *)src_.getBytes(),src_.width(),src_.height(),src_.width() * 4);
|
|
||||||
pixfmt_pre pixf_mask(src_buffer);
|
|
||||||
if (snap_to_pixels_)
|
|
||||||
{
|
|
||||||
renb_.blend_from(pixf_mask,
|
|
||||||
0,
|
|
||||||
std::floor(marker_tr.tx + .5),
|
|
||||||
std::floor(marker_tr.ty + .5),
|
|
||||||
unsigned(255*opacity));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
renb_.blend_from(pixf_mask,
|
|
||||||
0,
|
|
||||||
marker_tr.tx,
|
|
||||||
marker_tr.ty,
|
|
||||||
unsigned(255*opacity));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
using img_accessor_type = agg::image_accessor_clone<pixfmt_pre>;
|
|
||||||
using interpolator_type = agg::span_interpolator_linear<>;
|
|
||||||
//using span_gen_type = agg::span_image_filter_rgba_2x2<img_accessor_type,interpolator_type>;
|
|
||||||
using span_gen_type = agg::span_image_resample_rgba_affine<img_accessor_type>;
|
|
||||||
using renderer_type = agg::renderer_scanline_aa_alpha<renderer_base,
|
|
||||||
agg::span_allocator<color_type>,
|
|
||||||
span_gen_type>;
|
|
||||||
|
|
||||||
double p[8];
|
|
||||||
p[0] = 0; p[1] = 0;
|
|
||||||
p[2] = width; p[3] = 0;
|
|
||||||
p[4] = width; p[5] = height;
|
|
||||||
p[6] = 0; p[7] = height;
|
|
||||||
marker_tr.transform(&p[0], &p[1]);
|
|
||||||
marker_tr.transform(&p[2], &p[3]);
|
|
||||||
marker_tr.transform(&p[4], &p[5]);
|
|
||||||
marker_tr.transform(&p[6], &p[7]);
|
|
||||||
agg::span_allocator<color_type> sa;
|
|
||||||
agg::image_filter_lut filter;
|
|
||||||
filter.calculate(agg::image_filter_bilinear(), true);
|
|
||||||
agg::rendering_buffer marker_buf((unsigned char *)src_.getBytes(),
|
|
||||||
src_.width(),
|
|
||||||
src_.height(),
|
|
||||||
src_.width()*4);
|
|
||||||
pixfmt_pre pixf(marker_buf);
|
|
||||||
img_accessor_type ia(pixf);
|
|
||||||
agg::trans_affine final_tr(p, 0, 0, width, height);
|
|
||||||
if (snap_to_pixels_)
|
|
||||||
{
|
|
||||||
final_tr.tx = std::floor(final_tr.tx+.5);
|
|
||||||
final_tr.ty = std::floor(final_tr.ty+.5);
|
|
||||||
}
|
|
||||||
interpolator_type interpolator(final_tr);
|
|
||||||
span_gen_type sg(ia, interpolator, filter);
|
|
||||||
renderer_type rp(renb_,sa, sg, unsigned(opacity*255));
|
|
||||||
ras_.move_to_d(p[0],p[1]);
|
|
||||||
ras_.line_to_d(p[2],p[3]);
|
|
||||||
ras_.line_to_d(p[4],p[5]);
|
|
||||||
ras_.line_to_d(p[6],p[7]);
|
|
||||||
agg::render_scanlines(ras_, sl_, rp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
BufferType & buf_;
|
|
||||||
pixfmt_comp_type pixf_;
|
|
||||||
renderer_base renb_;
|
|
||||||
RasterizerType & ras_;
|
|
||||||
|
|
||||||
using raster_markers_dispatch<Detector>::src_;
|
|
||||||
using raster_markers_dispatch<Detector>::snap_to_pixels_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void build_ellipse(symbolizer_base const& sym, mapnik::feature_impl & feature, attributes const& vars, svg_storage_type & marker_ellipse, svg::svg_path_adapter & svg_path);
|
void build_ellipse(symbolizer_base const& sym, mapnik::feature_impl & feature, attributes const& vars, svg_storage_type & marker_ellipse, svg::svg_path_adapter & svg_path);
|
||||||
|
|
|
@ -32,17 +32,17 @@
|
||||||
|
|
||||||
namespace mapnik {
|
namespace mapnik {
|
||||||
|
|
||||||
template <typename T0, typename T1, typename T2>
|
template <typename VD, typename RD, typename RendererType, typename ContextType>
|
||||||
void render_markers_symbolizer(markers_symbolizer const& sym,
|
void render_markers_symbolizer(markers_symbolizer const& sym,
|
||||||
mapnik::feature_impl & feature,
|
mapnik::feature_impl & feature,
|
||||||
proj_transform const& prj_trans,
|
proj_transform const& prj_trans,
|
||||||
renderer_common const& common,
|
RendererType const& common,
|
||||||
box2d<double> const& clip_box,
|
box2d<double> const& clip_box,
|
||||||
T2 const& renderer_context)
|
ContextType const& renderer_context)
|
||||||
{
|
{
|
||||||
using namespace mapnik::svg;
|
using namespace mapnik::svg;
|
||||||
using vector_dispatch_type = T0;
|
using vector_dispatch_type = VD;
|
||||||
using raster_dispatch_type = T1;
|
using raster_dispatch_type = RD;
|
||||||
|
|
||||||
std::string filename = get<std::string>(sym, keys::file, feature, common.vars_, "shape://ellipse");
|
std::string filename = get<std::string>(sym, keys::file, feature, common.vars_, "shape://ellipse");
|
||||||
bool clip = get<value_bool>(sym, keys::clip, feature, common.vars_, false);
|
bool clip = get<value_bool>(sym, keys::clip, feature, common.vars_, false);
|
||||||
|
@ -71,18 +71,17 @@ void render_markers_symbolizer(markers_symbolizer const& sym,
|
||||||
if (filename == "shape://ellipse"
|
if (filename == "shape://ellipse"
|
||||||
&& (has_key<double>(sym,keys::width) || has_key<double>(sym,keys::height)))
|
&& (has_key<double>(sym,keys::width) || has_key<double>(sym,keys::height)))
|
||||||
{
|
{
|
||||||
svg_storage_type marker_ellipse;
|
svg_path_ptr marker_ellipse = std::make_shared<svg_storage_type>();
|
||||||
vertex_stl_adapter<svg_path_storage> stl_storage(marker_ellipse.source());
|
vertex_stl_adapter<svg_path_storage> stl_storage(marker_ellipse->source());
|
||||||
svg_path_adapter svg_path(stl_storage);
|
svg_path_adapter svg_path(stl_storage);
|
||||||
build_ellipse(sym, feature, common.vars_, marker_ellipse, svg_path);
|
build_ellipse(sym, feature, common.vars_, *marker_ellipse, svg_path);
|
||||||
svg_attribute_type attributes;
|
svg_attribute_type attributes;
|
||||||
bool result = push_explicit_style( (*stock_vector_marker)->attributes(), attributes, sym, feature, common.vars_);
|
bool result = push_explicit_style( (*stock_vector_marker)->attributes(), attributes, sym, feature, common.vars_);
|
||||||
auto image_transform = get_optional<transform_type>(sym, keys::image_transform);
|
auto image_transform = get_optional<transform_type>(sym, keys::image_transform);
|
||||||
if (image_transform) evaluate_transform(image_tr, feature, common.vars_, *image_transform);
|
if (image_transform) evaluate_transform(image_tr, feature, common.vars_, *image_transform);
|
||||||
box2d<double> bbox = marker_ellipse.bounding_box();
|
vector_dispatch_type rasterizer_dispatch(marker_ellipse,
|
||||||
vector_dispatch_type rasterizer_dispatch(svg_path,
|
svg_path,
|
||||||
result ? attributes : (*stock_vector_marker)->attributes(),
|
result ? attributes : (*stock_vector_marker)->attributes(),
|
||||||
bbox,
|
|
||||||
image_tr,
|
image_tr,
|
||||||
sym,
|
sym,
|
||||||
*common.detector_,
|
*common.detector_,
|
||||||
|
@ -124,9 +123,9 @@ void render_markers_symbolizer(markers_symbolizer const& sym,
|
||||||
svg_path_adapter svg_path(stl_storage);
|
svg_path_adapter svg_path(stl_storage);
|
||||||
svg_attribute_type attributes;
|
svg_attribute_type attributes;
|
||||||
bool result = push_explicit_style( (*stock_vector_marker)->attributes(), attributes, sym, feature, common.vars_);
|
bool result = push_explicit_style( (*stock_vector_marker)->attributes(), attributes, sym, feature, common.vars_);
|
||||||
vector_dispatch_type rasterizer_dispatch(svg_path,
|
vector_dispatch_type rasterizer_dispatch(*stock_vector_marker,
|
||||||
|
svg_path,
|
||||||
result ? attributes : (*stock_vector_marker)->attributes(),
|
result ? attributes : (*stock_vector_marker)->attributes(),
|
||||||
bbox,
|
|
||||||
image_tr,
|
image_tr,
|
||||||
sym,
|
sym,
|
||||||
*common.detector_,
|
*common.detector_,
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include <mapnik/marker_helpers.hpp>
|
#include <mapnik/marker_helpers.hpp>
|
||||||
#include <mapnik/marker.hpp>
|
#include <mapnik/marker.hpp>
|
||||||
#include <mapnik/marker_cache.hpp>
|
#include <mapnik/marker_cache.hpp>
|
||||||
|
#include <mapnik/agg_render_marker.hpp>
|
||||||
#include <mapnik/svg/svg_renderer_agg.hpp>
|
#include <mapnik/svg/svg_renderer_agg.hpp>
|
||||||
#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>
|
||||||
|
@ -59,6 +60,107 @@
|
||||||
|
|
||||||
namespace mapnik {
|
namespace mapnik {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template <typename SvgRenderer, typename Detector, typename RendererContext>
|
||||||
|
struct vector_markers_rasterizer_dispatch : public vector_markers_dispatch<Detector>
|
||||||
|
{
|
||||||
|
using renderer_base = typename SvgRenderer::renderer_base;
|
||||||
|
using vertex_source_type = typename SvgRenderer::vertex_source_type;
|
||||||
|
using attribute_source_type = typename SvgRenderer::attribute_source_type;
|
||||||
|
using pixfmt_type = typename renderer_base::pixfmt_type;
|
||||||
|
|
||||||
|
using BufferType = typename std::tuple_element<0,RendererContext>::type;
|
||||||
|
using RasterizerType = typename std::tuple_element<1,RendererContext>::type;
|
||||||
|
|
||||||
|
vector_markers_rasterizer_dispatch(svg_path_ptr const& src,
|
||||||
|
vertex_source_type & path,
|
||||||
|
svg_attribute_type const& attrs,
|
||||||
|
agg::trans_affine const& marker_trans,
|
||||||
|
symbolizer_base const& sym,
|
||||||
|
Detector & detector,
|
||||||
|
double scale_factor,
|
||||||
|
feature_impl & feature,
|
||||||
|
attributes const& vars,
|
||||||
|
bool snap_to_pixels,
|
||||||
|
RendererContext const& renderer_context)
|
||||||
|
: vector_markers_dispatch<Detector>(src, marker_trans, sym, detector, scale_factor, feature, vars),
|
||||||
|
buf_(std::get<0>(renderer_context)),
|
||||||
|
pixf_(buf_),
|
||||||
|
renb_(pixf_),
|
||||||
|
svg_renderer_(path, attrs),
|
||||||
|
ras_(std::get<1>(renderer_context)),
|
||||||
|
snap_to_pixels_(snap_to_pixels)
|
||||||
|
{
|
||||||
|
pixf_.comp_op(static_cast<agg::comp_op_e>(get<composite_mode_e>(sym, keys::comp_op, feature, vars, src_over)));
|
||||||
|
}
|
||||||
|
|
||||||
|
~vector_markers_rasterizer_dispatch() {}
|
||||||
|
|
||||||
|
void render_marker(agg::trans_affine const& marker_tr, double opacity)
|
||||||
|
{
|
||||||
|
render_vector_marker(svg_renderer_, ras_, renb_, this->src_->bounding_box(),
|
||||||
|
marker_tr, opacity, snap_to_pixels_);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
BufferType & buf_;
|
||||||
|
pixfmt_type pixf_;
|
||||||
|
renderer_base renb_;
|
||||||
|
SvgRenderer svg_renderer_;
|
||||||
|
RasterizerType & ras_;
|
||||||
|
bool snap_to_pixels_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Detector, typename RendererContext>
|
||||||
|
struct raster_markers_rasterizer_dispatch : public raster_markers_dispatch<Detector>
|
||||||
|
{
|
||||||
|
using BufferType = typename std::remove_reference<typename std::tuple_element<0,RendererContext>::type>::type;
|
||||||
|
using RasterizerType = typename std::tuple_element<1,RendererContext>::type;
|
||||||
|
|
||||||
|
using color_type = agg::rgba8;
|
||||||
|
using order_type = agg::order_rgba;
|
||||||
|
using pixel_type = agg::pixel32_type;
|
||||||
|
using blender_type = agg::comp_op_adaptor_rgba_pre<color_type, order_type>; // comp blender
|
||||||
|
using pixfmt_comp_type = agg::pixfmt_custom_blend_rgba<blender_type, BufferType>;
|
||||||
|
using renderer_base = agg::renderer_base<pixfmt_comp_type>;
|
||||||
|
|
||||||
|
raster_markers_rasterizer_dispatch(image_data_32 & src,
|
||||||
|
agg::trans_affine const& marker_trans,
|
||||||
|
symbolizer_base const& sym,
|
||||||
|
Detector & detector,
|
||||||
|
double scale_factor,
|
||||||
|
feature_impl & feature,
|
||||||
|
attributes const& vars,
|
||||||
|
RendererContext const& renderer_context,
|
||||||
|
bool snap_to_pixels = false)
|
||||||
|
: raster_markers_dispatch<Detector>(src, marker_trans, sym, detector, scale_factor, feature, vars),
|
||||||
|
buf_(std::get<0>(renderer_context)),
|
||||||
|
pixf_(buf_),
|
||||||
|
renb_(pixf_),
|
||||||
|
ras_(std::get<1>(renderer_context)),
|
||||||
|
snap_to_pixels_(snap_to_pixels)
|
||||||
|
{
|
||||||
|
pixf_.comp_op(static_cast<agg::comp_op_e>(get<composite_mode_e>(sym, keys::comp_op, feature, vars, src_over)));
|
||||||
|
}
|
||||||
|
|
||||||
|
~raster_markers_rasterizer_dispatch() {}
|
||||||
|
|
||||||
|
void render_marker(agg::trans_affine const& marker_tr, double opacity)
|
||||||
|
{
|
||||||
|
render_raster_marker(renb_, ras_, this->src_, marker_tr, opacity, this->scale_factor_, snap_to_pixels_);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
BufferType & buf_;
|
||||||
|
pixfmt_comp_type pixf_;
|
||||||
|
renderer_base renb_;
|
||||||
|
RasterizerType & ras_;
|
||||||
|
bool snap_to_pixels_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T0, typename T1>
|
template <typename T0, typename T1>
|
||||||
void agg_renderer<T0,T1>::process(markers_symbolizer const& sym,
|
void agg_renderer<T0,T1>::process(markers_symbolizer const& sym,
|
||||||
feature_impl & feature,
|
feature_impl & feature,
|
||||||
|
@ -94,8 +196,8 @@ void agg_renderer<T0,T1>::process(markers_symbolizer const& sym,
|
||||||
|
|
||||||
auto renderer_context = std::tie(render_buffer,*ras_ptr,pixmap_);
|
auto renderer_context = std::tie(render_buffer,*ras_ptr,pixmap_);
|
||||||
using context_type = decltype(renderer_context);
|
using context_type = decltype(renderer_context);
|
||||||
using vector_dispatch_type = vector_markers_rasterizer_dispatch_agg<svg_renderer_type, detector_type, context_type>;
|
using vector_dispatch_type = detail::vector_markers_rasterizer_dispatch<svg_renderer_type, detector_type, context_type>;
|
||||||
using raster_dispatch_type = raster_markers_rasterizer_dispatch_agg<detector_type, context_type>;
|
using raster_dispatch_type = detail::raster_markers_rasterizer_dispatch<detector_type, context_type>;
|
||||||
|
|
||||||
render_markers_symbolizer<vector_dispatch_type, raster_dispatch_type>(
|
render_markers_symbolizer<vector_dispatch_type, raster_dispatch_type>(
|
||||||
sym, feature, prj_trans, common_, clip_box, renderer_context);
|
sym, feature, prj_trans, common_, clip_box, renderer_context);
|
||||||
|
|
|
@ -32,21 +32,12 @@
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
|
|
||||||
void render_vector_marker(cairo_context & context, pixel_position const& pos,
|
void render_vector_marker(cairo_context & context, svg::svg_path_adapter & svg_path,
|
||||||
svg::svg_path_adapter & svg_path, box2d<double> const& bbox,
|
|
||||||
agg::pod_bvector<svg::path_attributes> const & attributes,
|
agg::pod_bvector<svg::path_attributes> const & attributes,
|
||||||
agg::trans_affine const& tr, double opacity, bool recenter)
|
box2d<double> const& bbox, agg::trans_affine const& tr,
|
||||||
|
double opacity)
|
||||||
{
|
{
|
||||||
using namespace mapnik::svg;
|
using namespace mapnik::svg;
|
||||||
agg::trans_affine mtx = tr;
|
|
||||||
if (recenter)
|
|
||||||
{
|
|
||||||
coord<double,2> c = bbox.center();
|
|
||||||
mtx = agg::trans_affine_translation(-c.x,-c.y);
|
|
||||||
mtx *= tr;
|
|
||||||
mtx.translate(pos.x, pos.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
agg::trans_affine transform;
|
agg::trans_affine transform;
|
||||||
|
|
||||||
for(unsigned i = 0; i < attributes.size(); ++i)
|
for(unsigned i = 0; i < attributes.size(); ++i)
|
||||||
|
@ -56,7 +47,7 @@ void render_vector_marker(cairo_context & context, pixel_position const& pos,
|
||||||
continue;
|
continue;
|
||||||
cairo_save_restore guard(context);
|
cairo_save_restore guard(context);
|
||||||
transform = attr.transform;
|
transform = attr.transform;
|
||||||
transform *= mtx;
|
transform *= tr;
|
||||||
|
|
||||||
// TODO - this 'is_valid' check is not used in the AGG renderer and also
|
// TODO - this 'is_valid' check is not used in the AGG renderer and also
|
||||||
// appears to lead to bogus results with
|
// appears to lead to bogus results with
|
||||||
|
|
|
@ -201,13 +201,20 @@ void cairo_renderer<T>::render_marker(pixel_position const& pos,
|
||||||
mapnik::svg_path_ptr vmarker = *marker.get_vector_data();
|
mapnik::svg_path_ptr vmarker = *marker.get_vector_data();
|
||||||
if (vmarker)
|
if (vmarker)
|
||||||
{
|
{
|
||||||
agg::trans_affine marker_tr = tr;
|
|
||||||
marker_tr *=agg::trans_affine_scaling(common_.scale_factor_);
|
|
||||||
box2d<double> bbox = vmarker->bounding_box();
|
box2d<double> bbox = vmarker->bounding_box();
|
||||||
|
agg::trans_affine marker_tr = tr;
|
||||||
|
if (recenter)
|
||||||
|
{
|
||||||
|
coord<double,2> c = bbox.center();
|
||||||
|
marker_tr = agg::trans_affine_translation(-c.x,-c.y);
|
||||||
|
marker_tr *= tr;
|
||||||
|
}
|
||||||
|
marker_tr *= agg::trans_affine_scaling(common_.scale_factor_);
|
||||||
agg::pod_bvector<svg::path_attributes> const & attributes = vmarker->attributes();
|
agg::pod_bvector<svg::path_attributes> const & attributes = vmarker->attributes();
|
||||||
svg::vertex_stl_adapter<svg::svg_path_storage> stl_storage(vmarker->source());
|
svg::vertex_stl_adapter<svg::svg_path_storage> stl_storage(vmarker->source());
|
||||||
svg::svg_path_adapter svg_path(stl_storage);
|
svg::svg_path_adapter svg_path(stl_storage);
|
||||||
render_vector_marker(context_, pos, svg_path, bbox, attributes, marker_tr, opacity, recenter);
|
marker_tr.translate(pos.x, pos.y);
|
||||||
|
render_vector_marker(context_, svg_path, attributes, bbox, marker_tr, opacity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (marker.is_bitmap())
|
else if (marker.is_bitmap())
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include <mapnik/attribute.hpp>
|
#include <mapnik/attribute.hpp>
|
||||||
#include <mapnik/marker.hpp>
|
#include <mapnik/marker.hpp>
|
||||||
#include <mapnik/marker_cache.hpp>
|
#include <mapnik/marker_cache.hpp>
|
||||||
|
#include <mapnik/marker_helpers.hpp>
|
||||||
#include <mapnik/renderer_common/process_markers_symbolizer.hpp>
|
#include <mapnik/renderer_common/process_markers_symbolizer.hpp>
|
||||||
|
|
||||||
// agg
|
// agg
|
||||||
|
@ -43,135 +44,67 @@ namespace mapnik
|
||||||
|
|
||||||
class feature_impl;
|
class feature_impl;
|
||||||
class proj_transform;
|
class proj_transform;
|
||||||
namespace svg { struct path_attributes; }
|
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template <typename RendererContext, typename SvgPath, typename Attributes, typename Detector>
|
template <typename RendererContext, typename Detector>
|
||||||
struct markers_dispatch : mapnik::noncopyable
|
struct vector_markers_dispatch_cairo : public vector_markers_dispatch<Detector>
|
||||||
{
|
{
|
||||||
markers_dispatch(SvgPath & marker,
|
vector_markers_dispatch_cairo(svg_path_ptr const& src,
|
||||||
Attributes const& attributes,
|
svg::svg_path_adapter & path,
|
||||||
box2d<double> const& bbox,
|
svg_attribute_type const& attrs,
|
||||||
agg::trans_affine const& marker_trans,
|
agg::trans_affine const& marker_trans,
|
||||||
markers_symbolizer const& sym,
|
markers_symbolizer const& sym,
|
||||||
Detector & detector,
|
Detector & detector,
|
||||||
double scale_factor,
|
double scale_factor,
|
||||||
feature_impl const& feature,
|
feature_impl & feature,
|
||||||
mapnik::attributes const& vars,
|
mapnik::attributes const& vars,
|
||||||
bool snap_to_pixels,
|
bool snap_to_pixels,
|
||||||
RendererContext const& renderer_context)
|
RendererContext const& renderer_context)
|
||||||
:marker_(marker),
|
: vector_markers_dispatch<Detector>(src, marker_trans, sym, detector, scale_factor, feature, vars),
|
||||||
attributes_(attributes),
|
path_(path),
|
||||||
bbox_(bbox),
|
attr_(attrs),
|
||||||
marker_trans_(marker_trans),
|
|
||||||
sym_(sym),
|
|
||||||
detector_(detector),
|
|
||||||
scale_factor_(scale_factor),
|
|
||||||
feature_(feature),
|
|
||||||
vars_(vars),
|
|
||||||
ctx_(std::get<0>(renderer_context))
|
ctx_(std::get<0>(renderer_context))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
void render_marker(agg::trans_affine const& marker_tr, double opacity)
|
||||||
template <typename T>
|
|
||||||
void add_path(T & path)
|
|
||||||
{
|
{
|
||||||
marker_placement_enum placement_method = get<marker_placement_enum>(
|
render_vector_marker(ctx_,
|
||||||
sym_, keys::markers_placement_type, feature_, vars_, MARKER_POINT_PLACEMENT);
|
path_,
|
||||||
bool ignore_placement = get<bool>(sym_, keys::ignore_placement, feature_, vars_, false);
|
attr_,
|
||||||
bool allow_overlap = get<bool>(sym_, keys::allow_overlap, feature_, vars_, false);
|
this->src_->bounding_box(),
|
||||||
bool avoid_edges = get<bool>(sym_, keys::avoid_edges, feature_, vars_, false);
|
marker_tr,
|
||||||
double opacity = get<double>(sym_, keys::opacity, feature_, vars_, 1.0);
|
opacity);
|
||||||
double spacing = get<double>(sym_, keys::spacing, feature_, vars_, 100.0);
|
|
||||||
double max_error = get<double>(sym_, keys::max_error, feature_, vars_, 0.2);
|
|
||||||
coord2d center = bbox_.center();
|
|
||||||
agg::trans_affine_translation recenter(-center.x, -center.y);
|
|
||||||
agg::trans_affine tr = recenter * marker_trans_;
|
|
||||||
markers_placement_params params { bbox_, tr, spacing * scale_factor_, max_error, allow_overlap, avoid_edges };
|
|
||||||
markers_placement_finder<T, label_collision_detector4> placement_finder(
|
|
||||||
placement_method, path, detector_, params);
|
|
||||||
double x, y, angle = .0;
|
|
||||||
while (placement_finder.get_point(x, y, angle, ignore_placement))
|
|
||||||
{
|
|
||||||
agg::trans_affine matrix = tr;
|
|
||||||
matrix.rotate(angle);
|
|
||||||
matrix.translate(x, y);
|
|
||||||
render_vector_marker(
|
|
||||||
ctx_,
|
|
||||||
pixel_position(x, y),
|
|
||||||
marker_,
|
|
||||||
bbox_,
|
|
||||||
attributes_,
|
|
||||||
matrix,
|
|
||||||
opacity,
|
|
||||||
false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SvgPath & marker_;
|
private:
|
||||||
Attributes const& attributes_;
|
svg::svg_path_adapter & path_;
|
||||||
box2d<double> const& bbox_;
|
svg_attribute_type const& attr_;
|
||||||
agg::trans_affine const& marker_trans_;
|
|
||||||
markers_symbolizer const& sym_;
|
|
||||||
Detector & detector_;
|
|
||||||
double scale_factor_;
|
|
||||||
feature_impl const& feature_;
|
|
||||||
attributes const& vars_;
|
|
||||||
cairo_context & ctx_;
|
cairo_context & ctx_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename RendererContext, typename Detector>
|
template <typename RendererContext, typename Detector>
|
||||||
struct raster_markers_dispatch : mapnik::noncopyable
|
struct raster_markers_dispatch_cairo : public raster_markers_dispatch<Detector>
|
||||||
{
|
{
|
||||||
raster_markers_dispatch(mapnik::image_data_32 & src,
|
raster_markers_dispatch_cairo(mapnik::image_data_32 & src,
|
||||||
agg::trans_affine const& marker_trans,
|
agg::trans_affine const& marker_trans,
|
||||||
markers_symbolizer const& sym,
|
markers_symbolizer const& sym,
|
||||||
Detector & detector,
|
Detector & detector,
|
||||||
double scale_factor,
|
double scale_factor,
|
||||||
feature_impl const& feature,
|
feature_impl & feature,
|
||||||
mapnik::attributes const& vars,
|
mapnik::attributes const& vars,
|
||||||
RendererContext const& renderer_context)
|
RendererContext const& renderer_context)
|
||||||
: src_(src),
|
: raster_markers_dispatch<Detector>(src, marker_trans, sym, detector, scale_factor, feature, vars),
|
||||||
detector_(detector),
|
|
||||||
sym_(sym),
|
|
||||||
marker_trans_(marker_trans),
|
|
||||||
scale_factor_(scale_factor),
|
|
||||||
feature_(feature),
|
|
||||||
vars_(vars),
|
|
||||||
ctx_(std::get<0>(renderer_context)) {}
|
ctx_(std::get<0>(renderer_context)) {}
|
||||||
|
|
||||||
template <typename T>
|
~raster_markers_dispatch_cairo() {}
|
||||||
void add_path(T & path)
|
|
||||||
|
void render_marker(agg::trans_affine const& marker_tr, double opacity)
|
||||||
{
|
{
|
||||||
marker_placement_enum placement_method = get<marker_placement_enum>(sym_, keys::markers_placement_type, feature_, vars_, MARKER_POINT_PLACEMENT);
|
ctx_.add_image(marker_tr, this->src_, opacity);
|
||||||
double opacity = get<double>(sym_, keys::opacity, feature_, vars_, 1.0);
|
|
||||||
double spacing = get<double>(sym_, keys::spacing, feature_, vars_, 100.0);
|
|
||||||
double max_error = get<double>(sym_, keys::max_error, feature_, vars_, 0.2);
|
|
||||||
bool allow_overlap = get<bool>(sym_, keys::allow_overlap, feature_, vars_, false);
|
|
||||||
bool avoid_edges = get<bool>(sym_, keys::avoid_edges, feature_, vars_, false);
|
|
||||||
bool ignore_placement = get<bool>(sym_, keys::ignore_placement, feature_, vars_, false);
|
|
||||||
box2d<double> bbox_(0,0, src_.width(),src_.height());
|
|
||||||
markers_placement_params params { bbox_, marker_trans_, spacing * scale_factor_, max_error, allow_overlap, avoid_edges };
|
|
||||||
markers_placement_finder<T, label_collision_detector4> placement_finder(
|
|
||||||
placement_method, path, detector_, params);
|
|
||||||
double x, y, angle = .0;
|
|
||||||
while (placement_finder.get_point(x, y, angle, ignore_placement))
|
|
||||||
{
|
|
||||||
agg::trans_affine matrix = marker_trans_;
|
|
||||||
matrix.rotate(angle);
|
|
||||||
matrix.translate(x, y);
|
|
||||||
ctx_.add_image(matrix, src_, opacity);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
image_data_32 & src_;
|
private:
|
||||||
Detector & detector_;
|
|
||||||
markers_symbolizer const& sym_;
|
|
||||||
agg::trans_affine const& marker_trans_;
|
|
||||||
double scale_factor_;
|
|
||||||
feature_impl const& feature_;
|
|
||||||
attributes const& vars_;
|
|
||||||
cairo_context & ctx_;
|
cairo_context & ctx_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -182,8 +115,6 @@ void cairo_renderer<T>::process(markers_symbolizer const& sym,
|
||||||
mapnik::feature_impl & feature,
|
mapnik::feature_impl & feature,
|
||||||
proj_transform const& prj_trans)
|
proj_transform const& prj_trans)
|
||||||
{
|
{
|
||||||
using svg_attribute_type = agg::pod_bvector<svg::path_attributes>;
|
|
||||||
|
|
||||||
cairo_save_restore guard(context_);
|
cairo_save_restore guard(context_);
|
||||||
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, common_.vars_, src_over);
|
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, common_.vars_, src_over);
|
||||||
context_.set_operator(comp_op);
|
context_.set_operator(comp_op);
|
||||||
|
@ -192,12 +123,11 @@ void cairo_renderer<T>::process(markers_symbolizer const& sym,
|
||||||
auto renderer_context = std::tie(context_);
|
auto renderer_context = std::tie(context_);
|
||||||
|
|
||||||
using RendererContextType = decltype(renderer_context);
|
using RendererContextType = decltype(renderer_context);
|
||||||
using vector_dispatch_type = detail::markers_dispatch<RendererContextType,
|
using vector_dispatch_type = detail::vector_markers_dispatch_cairo<RendererContextType,
|
||||||
svg::path_adapter<svg::vertex_stl_adapter<svg::svg_path_storage> >,
|
label_collision_detector4>;
|
||||||
svg_attribute_type,label_collision_detector4>;
|
|
||||||
|
|
||||||
using raster_dispatch_type = detail::raster_markers_dispatch<RendererContextType,
|
using raster_dispatch_type = detail::raster_markers_dispatch_cairo<RendererContextType,
|
||||||
label_collision_detector4>;
|
label_collision_detector4>;
|
||||||
|
|
||||||
|
|
||||||
render_markers_symbolizer<vector_dispatch_type, raster_dispatch_type>(
|
render_markers_symbolizer<vector_dispatch_type, raster_dispatch_type>(
|
||||||
|
|
|
@ -45,11 +45,14 @@ porting notes -->
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/feature.hpp>
|
#include <mapnik/feature.hpp>
|
||||||
|
#include <mapnik/geometry.hpp>
|
||||||
|
#include <mapnik/geom_util.hpp>
|
||||||
|
#include <mapnik/marker_helpers.hpp>
|
||||||
#include <mapnik/grid/grid_rasterizer.hpp>
|
#include <mapnik/grid/grid_rasterizer.hpp>
|
||||||
#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_render_marker.hpp>
|
||||||
#include <mapnik/grid/grid.hpp>
|
#include <mapnik/grid/grid.hpp>
|
||||||
#include <mapnik/grid/grid_marker_helpers.hpp>
|
|
||||||
|
|
||||||
#include <mapnik/debug.hpp>
|
#include <mapnik/debug.hpp>
|
||||||
#include <mapnik/geom_util.hpp>
|
#include <mapnik/geom_util.hpp>
|
||||||
|
@ -77,6 +80,111 @@ porting notes -->
|
||||||
|
|
||||||
namespace mapnik {
|
namespace mapnik {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template <typename SvgRenderer, typename Detector, typename RendererContext>
|
||||||
|
struct vector_markers_rasterizer_dispatch : public vector_markers_dispatch<Detector>
|
||||||
|
{
|
||||||
|
using renderer_base = typename SvgRenderer::renderer_base;
|
||||||
|
using vertex_source_type = typename SvgRenderer::vertex_source_type;
|
||||||
|
using attribute_source_type = typename SvgRenderer::attribute_source_type;
|
||||||
|
using pixfmt_type = typename renderer_base::pixfmt_type;
|
||||||
|
|
||||||
|
using BufferType = typename std::tuple_element<0,RendererContext>::type;
|
||||||
|
using RasterizerType = typename std::tuple_element<1,RendererContext>::type;
|
||||||
|
using PixMapType = typename std::tuple_element<2,RendererContext>::type;
|
||||||
|
|
||||||
|
vector_markers_rasterizer_dispatch(svg_path_ptr const& src,
|
||||||
|
vertex_source_type & path,
|
||||||
|
svg_attribute_type const& attrs,
|
||||||
|
agg::trans_affine const& marker_trans,
|
||||||
|
markers_symbolizer const& sym,
|
||||||
|
Detector & detector,
|
||||||
|
double scale_factor,
|
||||||
|
mapnik::feature_impl & feature,
|
||||||
|
attributes const& vars,
|
||||||
|
bool snap_to_pixels,
|
||||||
|
RendererContext const& renderer_context)
|
||||||
|
: vector_markers_dispatch<Detector>(src, marker_trans, sym, detector, scale_factor, feature, vars, snap_to_pixels),
|
||||||
|
buf_(std::get<0>(renderer_context)),
|
||||||
|
pixf_(buf_),
|
||||||
|
renb_(pixf_),
|
||||||
|
svg_renderer_(path, attrs),
|
||||||
|
ras_(std::get<1>(renderer_context)),
|
||||||
|
pixmap_(std::get<2>(renderer_context)),
|
||||||
|
placed_(false)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void render_marker(agg::trans_affine const& marker_tr, double opacity)
|
||||||
|
{
|
||||||
|
agg::scanline_bin sl_;
|
||||||
|
svg_renderer_.render_id(ras_, sl_, renb_, this->feature_.id(), marker_tr, opacity, this->src_->bounding_box());
|
||||||
|
if (!placed_)
|
||||||
|
{
|
||||||
|
pixmap_.add_feature(this->feature_);
|
||||||
|
placed_ = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
BufferType & buf_;
|
||||||
|
pixfmt_type pixf_;
|
||||||
|
renderer_base renb_;
|
||||||
|
SvgRenderer svg_renderer_;
|
||||||
|
RasterizerType & ras_;
|
||||||
|
PixMapType & pixmap_;
|
||||||
|
bool placed_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename RendererBase, typename RendererType, typename Detector, typename RendererContext>
|
||||||
|
struct raster_markers_rasterizer_dispatch : public raster_markers_dispatch<Detector>
|
||||||
|
{
|
||||||
|
using pixfmt_type = typename RendererBase::pixfmt_type;
|
||||||
|
using color_type = typename RendererBase::pixfmt_type::color_type;
|
||||||
|
|
||||||
|
using BufferType = typename std::tuple_element<0,RendererContext>::type;
|
||||||
|
using RasterizerType = typename std::tuple_element<1,RendererContext>::type;
|
||||||
|
using PixMapType = typename std::tuple_element<2,RendererContext>::type;
|
||||||
|
|
||||||
|
raster_markers_rasterizer_dispatch(image_data_32 & src,
|
||||||
|
agg::trans_affine const& marker_trans,
|
||||||
|
markers_symbolizer const& sym,
|
||||||
|
Detector & detector,
|
||||||
|
double scale_factor,
|
||||||
|
mapnik::feature_impl & feature,
|
||||||
|
attributes const& vars,
|
||||||
|
RendererContext const& renderer_context)
|
||||||
|
: raster_markers_dispatch<Detector>(src, marker_trans, sym, detector, scale_factor,
|
||||||
|
feature, vars, false),
|
||||||
|
buf_(std::get<0>(renderer_context)),
|
||||||
|
pixf_(buf_),
|
||||||
|
renb_(pixf_),
|
||||||
|
ras_(std::get<1>(renderer_context)),
|
||||||
|
pixmap_(std::get<2>(renderer_context)),
|
||||||
|
placed_(false)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void render_marker(agg::trans_affine const& marker_tr, double opacity)
|
||||||
|
{
|
||||||
|
render_raster_marker(RendererType(renb_), ras_, this->src_, this->feature_, marker_tr, opacity);
|
||||||
|
if (!placed_)
|
||||||
|
{
|
||||||
|
pixmap_.add_feature(this->feature_);
|
||||||
|
placed_ = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
BufferType & buf_;
|
||||||
|
pixfmt_type pixf_;
|
||||||
|
RendererBase renb_;
|
||||||
|
RasterizerType & ras_;
|
||||||
|
PixMapType & pixmap_;
|
||||||
|
bool placed_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void grid_renderer<T>::process(markers_symbolizer const& sym,
|
void grid_renderer<T>::process(markers_symbolizer const& sym,
|
||||||
mapnik::feature_impl & feature,
|
mapnik::feature_impl & feature,
|
||||||
|
@ -100,13 +208,13 @@ void grid_renderer<T>::process(markers_symbolizer const& sym,
|
||||||
|
|
||||||
auto renderer_context = std::tie(render_buf,*ras_ptr,pixmap_);
|
auto renderer_context = std::tie(render_buf,*ras_ptr,pixmap_);
|
||||||
using context_type = decltype(renderer_context);
|
using context_type = decltype(renderer_context);
|
||||||
using vector_dispatch_type = vector_markers_rasterizer_dispatch_grid<svg_renderer_type,
|
using vector_dispatch_type = detail::vector_markers_rasterizer_dispatch<svg_renderer_type,
|
||||||
detector_type,
|
detector_type,
|
||||||
context_type>;
|
context_type>;
|
||||||
using raster_dispatch_type = raster_markers_rasterizer_dispatch_grid<grid_renderer_base_type,
|
using raster_dispatch_type = detail::raster_markers_rasterizer_dispatch<grid_renderer_base_type,
|
||||||
renderer_type,
|
renderer_type,
|
||||||
detector_type,
|
detector_type,
|
||||||
context_type>;
|
context_type>;
|
||||||
render_markers_symbolizer<vector_dispatch_type, raster_dispatch_type>(
|
render_markers_symbolizer<vector_dispatch_type, raster_dispatch_type>(
|
||||||
sym, feature, prj_trans, common_, clip_box,renderer_context);
|
sym, feature, prj_trans, common_, clip_box,renderer_context);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,9 @@
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/marker_helpers.hpp>
|
#include <mapnik/marker_helpers.hpp>
|
||||||
|
|
||||||
|
#include "agg_ellipse.h"
|
||||||
|
#include "agg_color_rgba.h"
|
||||||
|
|
||||||
namespace mapnik {
|
namespace mapnik {
|
||||||
|
|
||||||
void build_ellipse(symbolizer_base const& sym, mapnik::feature_impl & feature, attributes const& vars, svg_storage_type & marker_ellipse, svg::svg_path_adapter & svg_path)
|
void build_ellipse(symbolizer_base const& sym, mapnik::feature_impl & feature, attributes const& vars, svg_storage_type & marker_ellipse, svg::svg_path_adapter & svg_path)
|
||||||
|
|
Loading…
Reference in a new issue