pixel snap raster markers and svg files loaded from the file system - partially addresses #1316
This commit is contained in:
parent
5e1a19cfda
commit
2fcd531345
2 changed files with 104 additions and 43 deletions
|
@ -48,6 +48,7 @@
|
||||||
#include "agg_image_accessors.h"
|
#include "agg_image_accessors.h"
|
||||||
#include "agg_pixfmt_rgba.h"
|
#include "agg_pixfmt_rgba.h"
|
||||||
#include "agg_span_image_filter_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>
|
||||||
|
@ -69,7 +70,8 @@ struct vector_markers_rasterizer_dispatch
|
||||||
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,
|
||||||
|
bool snap_to_pixels)
|
||||||
: buf_(render_buffer),
|
: buf_(render_buffer),
|
||||||
pixf_(buf_),
|
pixf_(buf_),
|
||||||
renb_(pixf_),
|
renb_(pixf_),
|
||||||
|
@ -79,7 +81,8 @@ struct vector_markers_rasterizer_dispatch
|
||||||
marker_trans_(marker_trans),
|
marker_trans_(marker_trans),
|
||||||
sym_(sym),
|
sym_(sym),
|
||||||
detector_(detector),
|
detector_(detector),
|
||||||
scale_factor_(scale_factor)
|
scale_factor_(scale_factor),
|
||||||
|
snap_to_pixels_(snap_to_pixels)
|
||||||
{
|
{
|
||||||
pixf_.comp_op(static_cast<agg::comp_op_e>(sym_.comp_op()));
|
pixf_.comp_op(static_cast<agg::comp_op_e>(sym_.comp_op()));
|
||||||
}
|
}
|
||||||
|
@ -116,6 +119,12 @@ struct vector_markers_rasterizer_dispatch
|
||||||
if (sym_.get_allow_overlap() ||
|
if (sym_.get_allow_overlap() ||
|
||||||
detector_.has_placement(transformed_bbox))
|
detector_.has_placement(transformed_bbox))
|
||||||
{
|
{
|
||||||
|
if (snap_to_pixels_)
|
||||||
|
{
|
||||||
|
// https://github.com/mapnik/mapnik/issues/1316
|
||||||
|
matrix.tx = std::floor(matrix.tx+.5);
|
||||||
|
matrix.ty = std::floor(matrix.ty+.5);
|
||||||
|
}
|
||||||
svg_renderer_.render(ras_, sl_, renb_, matrix, sym_.get_opacity(), bbox_);
|
svg_renderer_.render(ras_, sl_, renb_, matrix, sym_.get_opacity(), bbox_);
|
||||||
if (!sym_.get_ignore_placement())
|
if (!sym_.get_ignore_placement())
|
||||||
{
|
{
|
||||||
|
@ -153,6 +162,7 @@ private:
|
||||||
markers_symbolizer const& sym_;
|
markers_symbolizer const& sym_;
|
||||||
Detector & detector_;
|
Detector & detector_;
|
||||||
double scale_factor_;
|
double scale_factor_;
|
||||||
|
bool snap_to_pixels_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename BufferType, typename Rasterizer, typename Detector>
|
template <typename BufferType, typename Rasterizer, typename Detector>
|
||||||
|
@ -171,7 +181,8 @@ struct raster_markers_rasterizer_dispatch
|
||||||
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,
|
||||||
|
bool snap_to_pixels)
|
||||||
: buf_(render_buffer),
|
: buf_(render_buffer),
|
||||||
pixf_(buf_),
|
pixf_(buf_),
|
||||||
renb_(pixf_),
|
renb_(pixf_),
|
||||||
|
@ -180,7 +191,8 @@ struct raster_markers_rasterizer_dispatch
|
||||||
marker_trans_(marker_trans),
|
marker_trans_(marker_trans),
|
||||||
sym_(sym),
|
sym_(sym),
|
||||||
detector_(detector),
|
detector_(detector),
|
||||||
scale_factor_(scale_factor)
|
scale_factor_(scale_factor),
|
||||||
|
snap_to_pixels_(snap_to_pixels)
|
||||||
{
|
{
|
||||||
pixf_.comp_op(static_cast<agg::comp_op_e>(sym_.comp_op()));
|
pixf_.comp_op(static_cast<agg::comp_op_e>(sym_.comp_op()));
|
||||||
}
|
}
|
||||||
|
@ -245,8 +257,33 @@ struct raster_markers_rasterizer_dispatch
|
||||||
void render_raster_marker(agg::trans_affine const& marker_tr,
|
void render_raster_marker(agg::trans_affine const& marker_tr,
|
||||||
double opacity)
|
double opacity)
|
||||||
{
|
{
|
||||||
|
typedef agg::pixfmt_rgba32_pre pixfmt_pre;
|
||||||
double width = src_.width();
|
double width = src_.width();
|
||||||
double height = src_.height();
|
double height = src_.height();
|
||||||
|
if (std::fabs(1.0 - 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);
|
||||||
|
renb_.blend_from(pixf_mask,
|
||||||
|
0,
|
||||||
|
std::floor(marker_tr.tx + .5),
|
||||||
|
std::floor(marker_tr.ty + .5),
|
||||||
|
unsigned(255*sym_.get_opacity()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
typedef agg::image_accessor_clone<pixfmt_pre> img_accessor_type;
|
||||||
|
typedef agg::span_interpolator_linear<> interpolator_type;
|
||||||
|
//typedef agg::span_image_filter_rgba_2x2<img_accessor_type,interpolator_type> span_gen_type;
|
||||||
|
typedef agg::span_image_resample_rgba_affine<img_accessor_type> span_gen_type;
|
||||||
|
typedef agg::renderer_scanline_aa_alpha<renderer_base,
|
||||||
|
agg::span_allocator<color_type>,
|
||||||
|
span_gen_type> renderer_type;
|
||||||
|
|
||||||
double p[8];
|
double p[8];
|
||||||
p[0] = 0; p[1] = 0;
|
p[0] = 0; p[1] = 0;
|
||||||
p[2] = width; p[3] = 0;
|
p[2] = width; p[3] = 0;
|
||||||
|
@ -256,31 +293,31 @@ struct raster_markers_rasterizer_dispatch
|
||||||
marker_tr.transform(&p[2], &p[3]);
|
marker_tr.transform(&p[2], &p[3]);
|
||||||
marker_tr.transform(&p[4], &p[5]);
|
marker_tr.transform(&p[4], &p[5]);
|
||||||
marker_tr.transform(&p[6], &p[7]);
|
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]);
|
|
||||||
agg::span_allocator<color_type> sa;
|
agg::span_allocator<color_type> sa;
|
||||||
agg::image_filter_bilinear filter_kernel;
|
agg::image_filter_lut filter;
|
||||||
agg::image_filter_lut filter(filter_kernel, false);
|
filter.calculate(agg::image_filter_bilinear(), true);
|
||||||
agg::rendering_buffer marker_buf((unsigned char *)src_.getBytes(),
|
agg::rendering_buffer marker_buf((unsigned char *)src_.getBytes(),
|
||||||
src_.width(),
|
src_.width(),
|
||||||
src_.height(),
|
src_.height(),
|
||||||
src_.width()*4);
|
src_.width()*4);
|
||||||
agg::pixfmt_rgba32_pre pixf(marker_buf);
|
pixfmt_pre pixf(marker_buf);
|
||||||
typedef agg::image_accessor_clone<agg::pixfmt_rgba32_pre> img_accessor_type;
|
|
||||||
typedef agg::span_interpolator_linear<agg::trans_affine> interpolator_type;
|
|
||||||
typedef agg::span_image_filter_rgba_2x2<img_accessor_type,
|
|
||||||
interpolator_type> span_gen_type;
|
|
||||||
typedef agg::renderer_scanline_aa_alpha<renderer_base,
|
|
||||||
agg::span_allocator<color_type>,
|
|
||||||
span_gen_type> renderer_type;
|
|
||||||
img_accessor_type ia(pixf);
|
img_accessor_type ia(pixf);
|
||||||
interpolator_type interpolator(agg::trans_affine(p, 0, 0, width, height) );
|
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);
|
span_gen_type sg(ia, interpolator, filter);
|
||||||
renderer_type rp(renb_,sa, sg, unsigned(opacity*255));
|
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);
|
agg::render_scanlines(ras_, sl_, rp);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
agg::scanline_u8 sl_;
|
agg::scanline_u8 sl_;
|
||||||
|
@ -293,6 +330,7 @@ private:
|
||||||
markers_symbolizer const& sym_;
|
markers_symbolizer const& sym_;
|
||||||
Detector & detector_;
|
Detector & detector_;
|
||||||
double scale_factor_;
|
double scale_factor_;
|
||||||
|
bool snap_to_pixels_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,9 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
|
||||||
|
|
||||||
std::string filename = path_processor_type::evaluate(*sym.get_filename(), feature);
|
std::string filename = path_processor_type::evaluate(*sym.get_filename(), feature);
|
||||||
|
|
||||||
|
// https://github.com/mapnik/mapnik/issues/1316
|
||||||
|
bool snap_pixels = !mapnik::marker_cache::instance().is_uri(filename);
|
||||||
|
|
||||||
if (!filename.empty())
|
if (!filename.empty())
|
||||||
{
|
{
|
||||||
boost::optional<marker_ptr> mark = mapnik::marker_cache::instance().find(filename, true);
|
boost::optional<marker_ptr> mark = mapnik::marker_cache::instance().find(filename, true);
|
||||||
|
@ -120,8 +123,15 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
|
||||||
agg::trans_affine_translation recenter(-center.x, -center.y);
|
agg::trans_affine_translation recenter(-center.x, -center.y);
|
||||||
agg::trans_affine marker_trans = recenter * tr;
|
agg::trans_affine marker_trans = recenter * tr;
|
||||||
buf_type render_buffer(current_buffer_->raw_data(), width_, height_, width_ * 4);
|
buf_type render_buffer(current_buffer_->raw_data(), width_, height_, width_ * 4);
|
||||||
dispatch_type rasterizer_dispatch(render_buffer,svg_renderer,*ras_ptr,
|
dispatch_type rasterizer_dispatch(render_buffer,
|
||||||
bbox, marker_trans, sym, *detector_, scale_factor_);
|
svg_renderer,
|
||||||
|
*ras_ptr,
|
||||||
|
bbox,
|
||||||
|
marker_trans,
|
||||||
|
sym,
|
||||||
|
*detector_,
|
||||||
|
scale_factor_,
|
||||||
|
snap_pixels);
|
||||||
vertex_converter<box2d<double>, dispatch_type, markers_symbolizer,
|
vertex_converter<box2d<double>, dispatch_type, markers_symbolizer,
|
||||||
CoordTransform, proj_transform, agg::trans_affine, conv_types>
|
CoordTransform, proj_transform, agg::trans_affine, conv_types>
|
||||||
converter(query_extent_, rasterizer_dispatch, sym,t_,prj_trans,tr,scale_factor_);
|
converter(query_extent_, rasterizer_dispatch, sym,t_,prj_trans,tr,scale_factor_);
|
||||||
|
@ -153,8 +163,15 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
|
||||||
bool result = push_explicit_style( (*stock_vector_marker)->attributes(), attributes, sym);
|
bool result = push_explicit_style( (*stock_vector_marker)->attributes(), attributes, sym);
|
||||||
svg_renderer_type svg_renderer(svg_path, result ? attributes : (*stock_vector_marker)->attributes());
|
svg_renderer_type svg_renderer(svg_path, result ? attributes : (*stock_vector_marker)->attributes());
|
||||||
buf_type render_buffer(current_buffer_->raw_data(), width_, height_, width_ * 4);
|
buf_type render_buffer(current_buffer_->raw_data(), width_, height_, width_ * 4);
|
||||||
dispatch_type rasterizer_dispatch(render_buffer,svg_renderer,*ras_ptr,
|
dispatch_type rasterizer_dispatch(render_buffer,
|
||||||
bbox, marker_trans, sym, *detector_, scale_factor_);
|
svg_renderer,
|
||||||
|
*ras_ptr,
|
||||||
|
bbox,
|
||||||
|
marker_trans,
|
||||||
|
sym,
|
||||||
|
*detector_,
|
||||||
|
scale_factor_,
|
||||||
|
snap_pixels);
|
||||||
vertex_converter<box2d<double>, dispatch_type, markers_symbolizer,
|
vertex_converter<box2d<double>, dispatch_type, markers_symbolizer,
|
||||||
CoordTransform, proj_transform, agg::trans_affine, conv_types>
|
CoordTransform, proj_transform, agg::trans_affine, conv_types>
|
||||||
converter(query_extent_, rasterizer_dispatch, sym,t_,prj_trans,tr,scale_factor_);
|
converter(query_extent_, rasterizer_dispatch, sym,t_,prj_trans,tr,scale_factor_);
|
||||||
|
@ -184,8 +201,14 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
|
||||||
boost::optional<mapnik::image_ptr> marker = (*mark)->get_bitmap_data();
|
boost::optional<mapnik::image_ptr> marker = (*mark)->get_bitmap_data();
|
||||||
typedef raster_markers_rasterizer_dispatch<buf_type,rasterizer, detector_type> dispatch_type;
|
typedef raster_markers_rasterizer_dispatch<buf_type,rasterizer, detector_type> dispatch_type;
|
||||||
buf_type render_buffer(current_buffer_->raw_data(), width_, height_, width_ * 4);
|
buf_type render_buffer(current_buffer_->raw_data(), width_, height_, width_ * 4);
|
||||||
dispatch_type rasterizer_dispatch(render_buffer,*ras_ptr, **marker,
|
dispatch_type rasterizer_dispatch(render_buffer,
|
||||||
marker_trans, sym, *detector_, scale_factor_);
|
*ras_ptr,
|
||||||
|
**marker,
|
||||||
|
marker_trans,
|
||||||
|
sym,
|
||||||
|
*detector_,
|
||||||
|
scale_factor_,
|
||||||
|
true /*snap rasters no matter what*/);
|
||||||
vertex_converter<box2d<double>, dispatch_type, markers_symbolizer,
|
vertex_converter<box2d<double>, dispatch_type, markers_symbolizer,
|
||||||
CoordTransform, proj_transform, agg::trans_affine, conv_types>
|
CoordTransform, proj_transform, agg::trans_affine, conv_types>
|
||||||
converter(query_extent_, rasterizer_dispatch, sym,t_,prj_trans,tr,scale_factor_);
|
converter(query_extent_, rasterizer_dispatch, sym,t_,prj_trans,tr,scale_factor_);
|
||||||
|
|
Loading…
Reference in a new issue