Fix positioning problem with scale() transforms for SVG symbols. Centering transform applied in the wrong order. Thanks to Toby Collett.

This commit is contained in:
Robert Coup 2011-01-31 09:56:31 +00:00
parent 78ec8b1724
commit bea611a185
2 changed files with 14 additions and 17 deletions

View file

@ -214,21 +214,20 @@ void agg_renderer<T>::render_marker(const int x, const int y, marker &marker, co
renderer_base renb(pixf); renderer_base renb(pixf);
box2d<double> const& bbox = (*marker.get_vector_data())->bounding_box(); box2d<double> const& bbox = (*marker.get_vector_data())->bounding_box();
double x1 = bbox.minx(); coord<double,2> c = bbox.center();
double y1 = bbox.miny(); // center the svg marker on '0,0'
double x2 = bbox.maxx(); agg::trans_affine mtx = agg::trans_affine_translation(-c.x,-c.y);
double y2 = bbox.maxy(); // apply symbol transformation to get to map space
mtx *= tr;
agg::trans_affine recenter = agg::trans_affine_translation(0.5*(marker.width()-(x1+x2)),0.5*(marker.height()-(y1+y2))); mtx *= agg::trans_affine_scaling(scale_factor_);
// render the marker at the center of the marker box
mtx.translate(x+0.5 * marker.width(), y+0.5 * marker.height());
vertex_stl_adapter<svg_path_storage> stl_storage((*marker.get_vector_data())->source()); vertex_stl_adapter<svg_path_storage> stl_storage((*marker.get_vector_data())->source());
svg_path_adapter svg_path(stl_storage); svg_path_adapter svg_path(stl_storage);
svg_renderer<svg_path_adapter, svg_renderer<svg_path_adapter,
agg::pod_bvector<path_attributes> > svg_renderer(svg_path, agg::pod_bvector<path_attributes> > svg_renderer(svg_path,
(*marker.get_vector_data())->attributes()); (*marker.get_vector_data())->attributes());
agg::trans_affine mtx = recenter * tr;
mtx *= agg::trans_affine_scaling(scale_factor_);
mtx *= agg::trans_affine_translation(x, y);
svg_renderer.render(*ras_ptr, sl, renb, mtx, opacity, bbox); svg_renderer.render(*ras_ptr, sl, renb, mtx, opacity, bbox);
@ -236,9 +235,6 @@ void agg_renderer<T>::render_marker(const int x, const int y, marker &marker, co
} }
else else
{ {
//int px = int(floor(x - 0.5 * marker.width()));
// int py = int(floor(y - 0.5 * marker.height()));
pixmap_.set_rectangle_alpha2(**marker.get_bitmap_data(), x, y, opacity); pixmap_.set_rectangle_alpha2(**marker.get_bitmap_data(), x, y, opacity);
} }
} }

View file

@ -917,11 +917,12 @@ void cairo_renderer_base::render_marker(const int x, const int y, marker &marker
bbox = (*marker.get_vector_data())->bounding_box(); bbox = (*marker.get_vector_data())->bounding_box();
coord<double,2> c = bbox.center(); coord<double,2> c = bbox.center();
agg::trans_affine recenter = agg::trans_affine_translation(0.5 * marker.width()-c.x,0.5 * marker.height()-c.y); // center the svg marker on '0,0'
agg::trans_affine mtx = agg::trans_affine_translation(-c.x,-c.y);
agg::trans_affine mtx = tr; // apply symbol transformation to get to map space
mtx = recenter * mtx; mtx *= tr;
mtx *= agg::trans_affine_translation(x, y); // render the marker at the center of the marker box
mtx.translate(x+0.5 * marker.width(), y+0.5 * marker.height());
typedef coord_transform2<CoordTransform,geometry_type> path_type; typedef coord_transform2<CoordTransform,geometry_type> path_type;
mapnik::path_ptr vmarker = *marker.get_vector_data(); mapnik::path_ptr vmarker = *marker.get_vector_data();