AGG line/polygon_pattern_symbolizer add support for SVG patterns
This commit is contained in:
parent
d4224ae852
commit
18a7731d42
6 changed files with 64 additions and 32 deletions
|
@ -36,6 +36,7 @@
|
|||
#include <mapnik/request.hpp>
|
||||
#include <mapnik/gamma_method.hpp>
|
||||
#include <mapnik/renderer_common.hpp>
|
||||
#include <mapnik/image_data.hpp>
|
||||
// boost
|
||||
|
||||
#include <memory>
|
||||
|
@ -180,6 +181,9 @@ private:
|
|||
renderer_common common_;
|
||||
void setup(Map const& m);
|
||||
};
|
||||
}
|
||||
|
||||
std::shared_ptr<image_data_32> render_pattern(rasterizer & ras, marker const& marker);
|
||||
|
||||
} // namespace mapnik
|
||||
|
||||
#endif // MAPNIK_AGG_RENDERER_HPP
|
||||
|
|
|
@ -64,21 +64,14 @@ public:
|
|||
}
|
||||
|
||||
marker(boost::optional<mapnik::image_ptr> const& data)
|
||||
: bitmap_data_(data)
|
||||
{
|
||||
|
||||
}
|
||||
: bitmap_data_(data) {}
|
||||
|
||||
marker(boost::optional<mapnik::svg_path_ptr> const& data)
|
||||
: vector_data_(data)
|
||||
{
|
||||
|
||||
}
|
||||
: vector_data_(data) {}
|
||||
|
||||
marker(marker const& rhs)
|
||||
: bitmap_data_(rhs.bitmap_data_),
|
||||
vector_data_(rhs.vector_data_)
|
||||
{}
|
||||
vector_data_(rhs.vector_data_) {}
|
||||
|
||||
box2d<double> bounding_box() const
|
||||
{
|
||||
|
|
|
@ -350,10 +350,10 @@ void agg_renderer<T0,T1>::render_marker(pixel_position const& pos,
|
|||
vertex_stl_adapter<svg_path_storage> stl_storage((*marker.get_vector_data())->source());
|
||||
svg_path_adapter svg_path(stl_storage);
|
||||
svg_renderer_agg<svg_path_adapter,
|
||||
svg_attribute_type,
|
||||
renderer_type,
|
||||
pixfmt_comp_type> svg_renderer(svg_path,
|
||||
(*marker.get_vector_data())->attributes());
|
||||
svg_attribute_type,
|
||||
renderer_type,
|
||||
pixfmt_comp_type> svg_renderer(svg_path,
|
||||
(*marker.get_vector_data())->attributes());
|
||||
|
||||
svg_renderer.render(*ras_ptr, sl, renb, mtx, opacity, bbox);
|
||||
}
|
||||
|
@ -502,6 +502,34 @@ void agg_renderer<T0,T1>::draw_geo_extent(box2d<double> const& extent, mapnik::c
|
|||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<image_data_32> render_pattern(rasterizer & ras, marker const& marker)
|
||||
{
|
||||
using pixfmt = agg::pixfmt_rgba32_pre;
|
||||
using renderer_base = agg::renderer_base<pixfmt>;
|
||||
using renderer_solid = agg::renderer_scanline_aa_solid<renderer_base>;
|
||||
agg::scanline_u8 sl;
|
||||
double width = marker.width();
|
||||
double height = marker.height();
|
||||
std::shared_ptr<mapnik::image_data_32> image = std::make_shared<mapnik::image_data_32>(width, height);
|
||||
agg::rendering_buffer buf(image->getBytes(), image->width(), image->height(), image->width() * 4);
|
||||
pixfmt pixf(buf);
|
||||
renderer_base renb(pixf);
|
||||
mapnik::box2d<double> const& bbox = (*marker.get_vector_data())->bounding_box();
|
||||
mapnik::coord<double,2> c = bbox.center();
|
||||
agg::trans_affine mtx = agg::trans_affine_translation(-c.x,-c.y);
|
||||
mtx.translate(0.5 * image->width(), 0.5 * image->height());
|
||||
mapnik::svg::vertex_stl_adapter<mapnik::svg::svg_path_storage> stl_storage((*marker.get_vector_data())->source());
|
||||
mapnik::svg::svg_path_adapter svg_path(stl_storage);
|
||||
mapnik::svg::svg_renderer_agg<mapnik::svg::svg_path_adapter,
|
||||
agg::pod_bvector<mapnik::svg::path_attributes>,
|
||||
renderer_solid,
|
||||
agg::pixfmt_rgba32_pre > svg_renderer(svg_path,
|
||||
(*marker.get_vector_data())->attributes());
|
||||
|
||||
svg_renderer.render(ras, sl, renb, mtx, 1.0, bbox);
|
||||
return image;
|
||||
}
|
||||
|
||||
template class agg_renderer<image_32>;
|
||||
template void agg_renderer<image_32>::debug_draw_box<agg::rendering_buffer>(
|
||||
agg::rendering_buffer& buf,
|
||||
|
|
|
@ -102,16 +102,18 @@ void agg_renderer<T0,T1>::process(line_pattern_symbolizer const& sym,
|
|||
|
||||
std::string filename = get<std::string>(sym, keys::file, feature, common_.vars_);
|
||||
if (filename.empty()) return;
|
||||
boost::optional<mapnik::marker_ptr> mark = marker_cache::instance().find(filename, true);
|
||||
if (!mark) return;
|
||||
|
||||
if (!(*mark)->is_bitmap())
|
||||
boost::optional<mapnik::marker_ptr> marker_ptr = marker_cache::instance().find(filename, true);
|
||||
if (!marker_ptr || !(*marker_ptr)) return;
|
||||
boost::optional<image_ptr> pat;
|
||||
if ((*marker_ptr)->is_bitmap())
|
||||
{
|
||||
MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: Only images (not '" << filename << "') are supported in the line_pattern_symbolizer";
|
||||
return;
|
||||
boost::optional<image_ptr> pat = (*marker_ptr)->get_bitmap_data();
|
||||
}
|
||||
else
|
||||
{
|
||||
pat = render_pattern(*ras_ptr, **marker_ptr);
|
||||
}
|
||||
|
||||
boost::optional<image_ptr> pat = (*mark)->get_bitmap_data();
|
||||
if (!pat) return;
|
||||
|
||||
bool clip = get<value_bool>(sym, keys::clip, feature, common_.vars_, false);
|
||||
|
@ -139,7 +141,7 @@ void agg_renderer<T0,T1>::process(line_pattern_symbolizer const& sym,
|
|||
if (clip)
|
||||
{
|
||||
double padding = (double)(common_.query_extent_.width()/pixmap_.width());
|
||||
double half_stroke = (*mark)->width()/2.0;
|
||||
double half_stroke = (*marker_ptr)->width()/2.0;
|
||||
if (half_stroke > 1)
|
||||
padding *= half_stroke;
|
||||
if (std::fabs(offset) > 0)
|
||||
|
|
|
@ -32,6 +32,9 @@
|
|||
#include <mapnik/vertex_converters.hpp>
|
||||
#include <mapnik/parse_path.hpp>
|
||||
#include <mapnik/symbolizer.hpp>
|
||||
#include <mapnik/svg/svg_converter.hpp>
|
||||
#include <mapnik/svg/svg_renderer_agg.hpp>
|
||||
#include <mapnik/svg/svg_path_adapter.hpp>
|
||||
|
||||
// agg
|
||||
#include "agg_basics.h"
|
||||
|
@ -56,25 +59,27 @@ void agg_renderer<T0,T1>::process(polygon_pattern_symbolizer const& sym,
|
|||
{
|
||||
std::string filename = get<std::string>(sym, keys::file, feature, common_.vars_);
|
||||
if (filename.empty()) return;
|
||||
boost::optional<mapnik::marker_ptr> marker = marker_cache::instance().find(filename, true);
|
||||
if (!marker) return;
|
||||
boost::optional<mapnik::marker_ptr> marker_ptr = marker_cache::instance().find(filename, true);
|
||||
if (!marker_ptr || !(*marker_ptr)) return;
|
||||
|
||||
boost::optional<image_ptr> pat;
|
||||
|
||||
if (!(*marker)->is_bitmap())
|
||||
if ((*marker_ptr)->is_bitmap())
|
||||
{
|
||||
MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: Only images (not '" << filename << "') are supported in the line_pattern_symbolizer";
|
||||
return;
|
||||
pat = (*marker_ptr)->get_bitmap_data();
|
||||
}
|
||||
else
|
||||
{
|
||||
pat = render_pattern(*ras_ptr, **marker_ptr);
|
||||
}
|
||||
|
||||
pat = (*marker)->get_bitmap_data();
|
||||
|
||||
if (!pat) return;
|
||||
|
||||
using clipped_geometry_type = agg::conv_clip_polygon<geometry_type>;
|
||||
using path_type = coord_transform<CoordTransform,clipped_geometry_type>;
|
||||
|
||||
agg::rendering_buffer buf(current_buffer_->raw_data(), current_buffer_->width(), current_buffer_->height(), current_buffer_->width() * 4);
|
||||
agg::rendering_buffer buf(current_buffer_->raw_data(), current_buffer_->width(),
|
||||
current_buffer_->height(), current_buffer_->width() * 4);
|
||||
ras_ptr->reset();
|
||||
double gamma = get<value_double>(sym, keys::gamma, feature, common_.vars_, 1.0);
|
||||
gamma_method_enum gamma_method = get<gamma_method_enum>(sym, keys::gamma_method, feature, common_.vars_, GAMMA_POWER);
|
||||
|
|
|
@ -155,7 +155,7 @@ int main (int argc,char** argv)
|
|||
std::clog << "found width of '" << w << "' and height of '" << h << "'\n";
|
||||
}
|
||||
// 10 pixel buffer to avoid edge clipping of 100% svg's
|
||||
mapnik::image_32 im(w+10,h+10);
|
||||
mapnik::image_32 im(w+0,h+0);
|
||||
agg::rendering_buffer buf(im.raw_data(), im.width(), im.height(), im.width() * 4);
|
||||
pixfmt pixf(buf);
|
||||
renderer_base renb(pixf);
|
||||
|
|
Loading…
Reference in a new issue