add support for geometry-transform in pattern symbolizers - closes #2065

This commit is contained in:
Dane Springmeyer 2013-11-05 16:40:09 -08:00
parent 2db7d7c390
commit 0250538149
13 changed files with 283 additions and 58 deletions

View file

@ -140,7 +140,7 @@ void agg_renderer<T>::process(line_pattern_symbolizer const& sym,
clip_box.pad(padding); clip_box.pad(padding);
} }
typedef boost::mpl::vector<clip_line_tag,transform_tag,offset_transform_tag,simplify_tag,smooth_tag> conv_types; typedef boost::mpl::vector<clip_line_tag,transform_tag,offset_transform_tag,affine_transform_tag,simplify_tag,smooth_tag> conv_types;
vertex_converter<box2d<double>, rasterizer_type, line_pattern_symbolizer, vertex_converter<box2d<double>, rasterizer_type, line_pattern_symbolizer,
CoordTransform, proj_transform, agg::trans_affine, conv_types> CoordTransform, proj_transform, agg::trans_affine, conv_types>
converter(clip_box,ras,sym,t_,prj_trans,tr,scale_factor_); converter(clip_box,ras,sym,t_,prj_trans,tr,scale_factor_);
@ -149,6 +149,7 @@ void agg_renderer<T>::process(line_pattern_symbolizer const& sym,
converter.set<transform_tag>(); //always transform converter.set<transform_tag>(); //always transform
if (sym.simplify_tolerance() > 0.0) converter.set<simplify_tag>(); // optional simplify converter if (sym.simplify_tolerance() > 0.0) converter.set<simplify_tag>(); // optional simplify converter
if (std::fabs(sym.offset()) > 0.0) converter.set<offset_transform_tag>(); // parallel offset if (std::fabs(sym.offset()) > 0.0) converter.set<offset_transform_tag>(); // parallel offset
converter.set<affine_transform_tag>(); // optional affine transform
if (sym.smooth() > 0.0) converter.set<smooth_tag>(); // optional smooth converter if (sym.smooth() > 0.0) converter.set<smooth_tag>(); // optional smooth converter
BOOST_FOREACH(geometry_type & geom, feature.paths()) BOOST_FOREACH(geometry_type & geom, feature.paths())

View file

@ -148,13 +148,14 @@ void agg_renderer<T>::process(polygon_pattern_symbolizer const& sym,
agg::trans_affine tr; agg::trans_affine tr;
evaluate_transform(tr, feature, sym.get_transform()); evaluate_transform(tr, feature, sym.get_transform());
typedef boost::mpl::vector<clip_poly_tag,transform_tag,simplify_tag,smooth_tag> conv_types; typedef boost::mpl::vector<clip_poly_tag,transform_tag,affine_transform_tag,simplify_tag,smooth_tag> conv_types;
vertex_converter<box2d<double>, rasterizer, polygon_pattern_symbolizer, vertex_converter<box2d<double>, rasterizer, polygon_pattern_symbolizer,
CoordTransform, proj_transform, agg::trans_affine, conv_types> CoordTransform, proj_transform, agg::trans_affine, conv_types>
converter(clip_box,*ras_ptr,sym,t_,prj_trans,tr,scale_factor_); converter(clip_box,*ras_ptr,sym,t_,prj_trans,tr,scale_factor_);
if (prj_trans.equal() && sym.clip()) converter.set<clip_poly_tag>(); //optional clip (default: true) if (prj_trans.equal() && sym.clip()) converter.set<clip_poly_tag>(); //optional clip (default: true)
converter.set<transform_tag>(); //always transform converter.set<transform_tag>(); //always transform
converter.set<affine_transform_tag>(); // optional affine transform
if (sym.simplify_tolerance() > 0.0) converter.set<simplify_tag>(); // optional simplify converter if (sym.simplify_tolerance() > 0.0) converter.set<simplify_tag>(); // optional simplify converter
if (sym.smooth() > 0.0) converter.set<smooth_tag>(); // optional smooth converter if (sym.smooth() > 0.0) converter.set<smooth_tag>(); // optional smooth converter

View file

@ -27,6 +27,10 @@
#include <mapnik/grid/grid_renderer_base.hpp> #include <mapnik/grid/grid_renderer_base.hpp>
#include <mapnik/grid/grid.hpp> #include <mapnik/grid/grid.hpp>
#include <mapnik/line_pattern_symbolizer.hpp> #include <mapnik/line_pattern_symbolizer.hpp>
#include <mapnik/marker.hpp>
#include <mapnik/marker_cache.hpp>
#include <mapnik/vertex_converters.hpp>
#include <mapnik/parse_path.hpp>
// agg // agg
#include "agg_rasterizer_scanline_aa.h" #include "agg_rasterizer_scanline_aa.h"
@ -45,10 +49,27 @@ void grid_renderer<T>::process(line_pattern_symbolizer const& sym,
mapnik::feature_impl & feature, mapnik::feature_impl & feature,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
std::string filename = path_processor_type::evaluate( *sym.get_filename(), feature);
boost::optional<marker_ptr> mark = marker_cache::instance().find(filename,true);
if (!mark) return;
if (!(*mark)->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 = (*mark)->get_bitmap_data();
if (!pat) return;
typedef coord_transform<CoordTransform,geometry_type> path_type; typedef coord_transform<CoordTransform,geometry_type> path_type;
typedef typename grid_renderer_base_type::pixfmt_type pixfmt_type; typedef typename grid_renderer_base_type::pixfmt_type pixfmt_type;
typedef typename grid_renderer_base_type::pixfmt_type::color_type color_type; typedef typename grid_renderer_base_type::pixfmt_type::color_type color_type;
typedef agg::renderer_scanline_bin_solid<grid_renderer_base_type> renderer_type; typedef agg::renderer_scanline_bin_solid<grid_renderer_base_type> renderer_type;
typedef boost::mpl::vector<clip_line_tag, transform_tag,
offset_transform_tag, affine_transform_tag,
simplify_tag, smooth_tag, stroke_tag> conv_types;
agg::scanline_bin sl; agg::scanline_bin sl;
grid_rendering_buffer buf(pixmap_.raw_data(), width_, height_, width_); grid_rendering_buffer buf(pixmap_.raw_data(), width_, height_, width_);
@ -59,19 +80,45 @@ void grid_renderer<T>::process(line_pattern_symbolizer const& sym,
ras_ptr->reset(); ras_ptr->reset();
// TODO - actually handle image dimensions int stroke_width = (*pat)->width();
int stroke_width = 2;
for (std::size_t i=0;i<feature.num_geometries();++i) agg::trans_affine tr;
evaluate_transform(tr, feature, sym.get_transform());
box2d<double> clipping_extent = query_extent_;
if (sym.clip())
{
double padding = (double)(query_extent_.width()/pixmap_.width());
double half_stroke = stroke_width/2.0;
if (half_stroke > 1)
padding *= half_stroke;
if (std::fabs(sym.offset()) > 0)
padding *= std::fabs(sym.offset()) * 1.2;
padding *= scale_factor_;
clipping_extent.pad(padding);
}
// to avoid the complexity of using an agg pattern filter instead
// we create a line_symbolizer in order to fake the pattern
stroke str;
str.set_width(stroke_width);
line_symbolizer line(str);
vertex_converter<box2d<double>, grid_rasterizer, line_symbolizer,
CoordTransform, proj_transform, agg::trans_affine, conv_types>
converter(clipping_extent,*ras_ptr,line,t_,prj_trans,tr,scale_factor_);
if (sym.clip()) converter.set<clip_line_tag>(); // optional clip (default: true)
converter.set<transform_tag>(); // always transform
if (std::fabs(sym.offset()) > 0.0) converter.set<offset_transform_tag>(); // parallel offset
converter.set<affine_transform_tag>(); // optional affine transform
if (sym.simplify_tolerance() > 0.0) converter.set<simplify_tag>(); // optional simplify converter
if (sym.smooth() > 0.0) converter.set<smooth_tag>(); // optional smooth converter
converter.set<stroke_tag>(); //always stroke
BOOST_FOREACH( geometry_type & geom, feature.paths())
{ {
geometry_type & geom = feature.get_geometry(i);
if (geom.size() > 1) if (geom.size() > 1)
{ {
path_type path(t_,geom,prj_trans); converter.apply(geom);
agg::conv_stroke<path_type> stroke(path);
stroke.generator().miter_limit(4.0);
stroke.generator().width(stroke_width * scale_factor_);
ras_ptr->add_path(stroke);
} }
} }

View file

@ -31,6 +31,9 @@
#include <mapnik/grid/grid.hpp> #include <mapnik/grid/grid.hpp>
#include <mapnik/polygon_pattern_symbolizer.hpp> #include <mapnik/polygon_pattern_symbolizer.hpp>
#include <mapnik/vertex_converters.hpp> #include <mapnik/vertex_converters.hpp>
#include <mapnik/marker.hpp>
#include <mapnik/marker_cache.hpp>
#include <mapnik/parse_path.hpp>
// agg // agg
#include "agg_rasterizer_scanline_aa.h" #include "agg_rasterizer_scanline_aa.h"
@ -48,6 +51,20 @@ void grid_renderer<T>::process(polygon_pattern_symbolizer const& sym,
mapnik::feature_impl & feature, mapnik::feature_impl & feature,
proj_transform const& prj_trans) proj_transform const& prj_trans)
{ {
std::string filename = path_processor_type::evaluate( *sym.get_filename(), feature);
boost::optional<marker_ptr> mark = marker_cache::instance().find(filename,true);
if (!mark) return;
if (!(*mark)->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 = (*mark)->get_bitmap_data();
if (!pat) return;
ras_ptr->reset(); ras_ptr->reset();
agg::trans_affine tr; agg::trans_affine tr;

View file

@ -0,0 +1,59 @@
{
"keys": [
"",
"1"
],
"data": {},
"grid": [
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!! !!!!!!!!!!! ",
" !!!!!!!!!!! !!!!!!!!!!! ",
" !!!!!!!!!!! !!!!!!!!!!! ",
" !!!!!!!!!!! !!!!!!!!!!! ",
" !!!!!!!!!!! !!!!!!!!!!! ",
" !!!!!!!!!!! !!!!!!!!!!! ",
" !!!!!!!!!!! !!!!!!!!!!! ",
" !!!!!!!!!!! !!!!!!!!!!! ",
" !!!!!!!!!!! !!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" "
]
}

View file

@ -32,33 +32,33 @@
" ", " ",
" ", " ",
" ", " ",
" ", " !!!!!!!!! ############# $$$$$$$$$$$$ %%%%%%%%%%% ",
" !!!!! ########### $$$$$$$$$$ %%%%%%% ", " !!!!!!!!!!!!!!!!! ##################### $$$$$$$$$$$$$$$$$$$$ %%%%%%%%%%%%%%%%%%% ",
" !!! !!! ### ### $$$ $$$ %%%% %%% ", " !!!!!!!!!!!!!!!!!!!!!!! ######################### $$$$$$$$$$$$$$$$$$$$$$$$ %%%%%%%%%%%%%%%%%%%%%%% ",
" !! !! ## ## $$ $$ %% %%% ", " !!!!!!!!!!! !!!!!!!!!!!! ######## ######### $$$$$$$$$ $$$$$$$$$$ %%%%%%%%%% %%%%%%%%%% ",
" !! !! ## ## $ $$ %% % ", " !!!!!!! !!!!!!! ####### ####### $$$$$$ $$$$$$$ %%%%%%% %%%%%%%% ",
" !! ! # # $$ $ % %% ", " !!!!!! !!!!!! ###### ###### $$$$$ $$$$$$ %%%%% %%%%%% ",
" ! !! # # $$ $ %% % ", " !!!!!! !!!!! ##### ##### $$$$$ $$$$$ %%%%% %%%%% ",
" ! !! # # $ $ %% % ", " !!!! !!!!! ##### ##### $$$$ $$$$$ %%%% %%%%% ",
" !! ! # # $ $ % % ", " !!!! !!!! #### #### $$$$ $$$$ %%%% %%%% ",
" ! ! # # $ $ % % ", " !!!! !!!! #### #### $$$ $$$$ %%%% %%%% ",
" ! ! # # $ $ % % ", " !!!! !!!! #### #### $$$$ $$$ %%%% %%%% ",
" ! ! # # $ $ % % ", " !!! !!!! ### ### $$$$ $$$ %%%% %%% ",
" ! ! &&&&& # $ $ % % ", " !!! !!! #&&&&& ### $$$ $$$ %%% %%% ",
" ! '''''''''''''''''''''''''''''' # # $ $ % (((((((((((( ", " !!! ''''''''''''''''''''''''''''''! ### ### $$$ $$$ %%% ((((((((((((% ",
" ! ! # # $ $ % % ", " !!! !!! ### ### $$$$ $$$ %%% %%% ",
" ! ! # $ $ % ", " !!! !!!! #### #### $$$$ $$$ %%%% %%% ",
" ! # # $ % ", " !!!! !!! ### #### $$$ $$$$ %%% %%%% ",
" ! ! ## # $ $ % % ", " !!!! !!!! #### #### $$$$ $$$$ %%%% %%%% ",
" ! ! # # $ $ % % ", " !!!! !!!!! #### #### $$$$ $$$$$ %%%% %%%%% ",
" !! ! # # $ $ % % ", " !!!!! !!!!! ##### ##### $$$$ $$$$$ %%%%% %%%%% ",
" !! ! ## ## $$ $ % % ", " !!!!! !!!!! ###### ###### $$$$$$ $$$$$$ %%%%%% %%%%% ",
" ! !! # # $ $$ %% %% ", " !!!!!! !!!!!! ####### ####### $$$$$$ $$$$$$$ %%%%%%% %%%%%% ",
" !! !! ## ### $$ $$ %% %% ", " !!!!!!!! !!!!!!!! ########## ########## $$$$$$$$$ $$$$$$$$$ %%%%%%%% %%%%%%%%% ",
" !! !! ### ### $$$ $$$ %%% %%% ", " !!!!!!!!!!!!!!!!!!!!!!!!! ####################### $$$$$$$$$$$$$$$$$$$$$$$$ %%%%%%%%%%%%%%%%%%%%%%%%% ",
" !!!!! !!!!!! ######### $$$$$$$$$$ %%%%%%%%%%%% ", " !!!!!!!!!!!!!!!!!!!!! ################### $$$$$$$$$$$$$$$$$$$$ %%%%%%%%%%%%%%%%%%%%% ",
" ", " !!!!!!!!!!!!!!! ########### $$$$$$$$$$$$$ %%%%%%%%%%%%%% ",
" ", " !!! ",
" ", " ",
" ", " ",
" ", " ",

View file

@ -1,12 +1,12 @@
{ {
"keys": [ "keys": [
"", "",
"4",
"3", "3",
"4",
"2", "2",
"1", "1",
"8",
"7", "7",
"8",
"6", "6",
"5" "5"
], ],
@ -67,24 +67,24 @@
" ", " ",
" ", " ",
" ", " ",
" ", " !! ",
" !!!!!!!! ##### ##### $$$$$$$$$$ %%%%%%%%% ", " ########## !!!!!!!!!!!!! $$$$$$$$$$$$ %%%%%%%%%%% ",
" !! !! ### ## $$ $$ %% %% ", " #### #### !!! !!! $$$ $$$ %%%% %%%% ",
" !! ! # # $$ $$ %% %% ", " ### ### !!! !!! $$$ $$ %% %%% ",
" !! !! # # $$ $ % % ", " ## ## !! !! $$ $$ %% %% ",
" ! !! # # $ $ % % ", " ## ## !! !! $$ $$ %% %%",
" ! ! # # $ $ % %", " # ## ! ! $$ $$ %% %",
"! ! # $ $ % ", "## # !! !! $ $ % %",
"! ! # $ $ % ", "# # !&&&& ! $ $ %% ",
"&&&&&&&&&&&&&&&&&&&&&&&&&& ''''''''''''''''''''''# (((((((((((((((((((((((((( )))))))))))))))))))))))))", "'''''''''''''''''''''''''' !&&&&&&&&&&&&&&&&&&&&&&&&&! (((((((((((((((((((((((((( %)))))))))))))))))))))))))",
"! ! $ $ % ", "# # !! !! $ $ %% ",
"! ! # # $ $ % %", "# # ! ! $$ $ % %",
" ! ! ## # $ $ %% %", "## ## !! !! $ $ %% %",
" !! ! # # $ $ % % ", " ## ## !! !! $$ $$ %% %%",
" !! !! ## ## $ $ %% % ", " ## ## !! !! $$$ $$ %% %%% ",
" ! ! ## # $$ $$ %% %% ", " ### ### !!! !!! $$ $$$ %%% %% ",
" !!! !!! ### ### $$$ $$ %%% %% ", " #### #### !!!!! !!!!! $$$$$ $$$$$ %%%% %%%%% ",
" !!!!!!!!!! ##### $$$$$$$$ %%%%%%%% ", " ############ !!!!!!!!! $$$$$$$$$$ %%%%%%%%%%% ",
" ", " ",
" ", " ",
" ", " ",

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

View file

@ -0,0 +1,99 @@
<Map background-color="#eee" srs="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs">
<Style name="polygon">
<Rule>
<PolygonPatternSymbolizer
file="../../data/images/stripes_pattern.png"
geometry-transform="translate(2,2)"
/>
<PolygonPatternSymbolizer
file="../data/pattern.png"
/>
</Rule>
</Style>
<Style name="line">
<Rule>
<LinePatternSymbolizer
file="../../data/images/stripes_pattern.png"
geometry-transform="translate(-3,-3)"
/>
<LinePatternSymbolizer
file="../../data/images/stripes_pattern.png"
geometry-transform="translate(3,3)"
/>
</Rule>
</Style>
<Style name="point">
<Rule>
<MarkersSymbolizer
fill="#437"
width="10"
stroke-width="0"
transform="translate(2,2)"
allow-overlap="true"
/>
<MarkersSymbolizer
fill="#ec3"
width="10"
stroke-width="0"
allow-overlap="true"
/>
</Rule>
</Style>
<Layer name="polygon" srs="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs">
<StyleName>polygon</StyleName>
<Datasource>
<Parameter name="type">csv</Parameter>
<Parameter name="inline">
wkt
"POLYGON ((1 1, 4 1, 4 4, 1 4, 1 1), (2 2, 2 3, 3 3, 3 2, 2 2))"
</Parameter>
</Datasource>
</Layer>
<Layer name="line" srs="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs">
<StyleName>line</StyleName>
<Datasource>
<Parameter name="type">csv</Parameter>
<Parameter name="inline">
wkt
"LINESTRING (0.5 0.5, 4.5 4.5)"
</Parameter>
</Datasource>
</Layer>
<Layer name="point" srs="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs">
<StyleName>point</StyleName>
<Datasource>
<Parameter name="type">csv</Parameter>
<Parameter name="inline">
wkt
"POINT (1 4)"
</Parameter>
</Datasource>
</Layer>
<!-- points to frame data view -->
<Style name="frame">
<Rule>
<PointSymbolizer />
</Rule>
</Style>
<Layer name="frame" srs="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs">
<StyleName>frame</StyleName>
<Datasource>
<Parameter name="type">csv</Parameter>
<Parameter name="inline">
x,y
0,0
5,0
0,5
5,5
</Parameter>
</Datasource>
</Layer>
</Map>

View file

@ -100,6 +100,7 @@ files = {
'shield-on-polygon': {'sizes':[(600,400)]}, 'shield-on-polygon': {'sizes':[(600,400)]},
'shield-on-line-spacing-eq-width': {'sizes':[(600,400)]}, 'shield-on-line-spacing-eq-width': {'sizes':[(600,400)]},
'geometry-transform-translate': {'sizes':[(200,200)]}, 'geometry-transform-translate': {'sizes':[(200,200)]},
'geometry-transform-translate-patterns': {'sizes':[(200,200)]},
'marker-svg-opacity':{}, 'marker-svg-opacity':{},
'marker-svg-opacity2':{}, 'marker-svg-opacity2':{},
'marker-svg-empty-g-element':{}, 'marker-svg-empty-g-element':{},