Browse files

Merge branch 'master' of github.com:mapnik/mapnik

  • Loading branch information...
2 parents 906de8e + e404404 commit 44769def3c056464228d1af3b06be90dabc1e9e4 @springmeyer springmeyer committed Jul 5, 2012
View
21 bindings/python/mapnik_markers_symbolizer.cpp
@@ -96,11 +96,6 @@ void export_markers_symbolizer()
.value("LINE_PLACEMENT",mapnik::MARKER_LINE_PLACEMENT)
;
- mapnik::enumeration_<mapnik::marker_type_e>("marker_type")
- .value("ARROW",mapnik::MARKER_ARROW)
- .value("ELLIPSE",mapnik::MARKER_ELLIPSE)
- ;
-
class_<markers_symbolizer>("MarkersSymbolizer",
init<>("Default Markers Symbolizer - blue arrow"))
.def (init<mapnik::path_expression_ptr>("<path expression ptr>"))
@@ -128,27 +123,23 @@ void export_markers_symbolizer()
&mapnik::get_svg_transform<markers_symbolizer>,
&mapnik::set_svg_transform<markers_symbolizer>)
.add_property("width",
- &markers_symbolizer::get_width,
+ make_function(&markers_symbolizer::get_width,
+ return_value_policy<copy_const_reference>()),
&markers_symbolizer::set_width,
"Set/get the marker width")
.add_property("height",
- &markers_symbolizer::get_height,
+ make_function(&markers_symbolizer::get_height,
+ return_value_policy<copy_const_reference>()),
&markers_symbolizer::set_height,
"Set/get the marker height")
.add_property("fill",
- make_function(&markers_symbolizer::get_fill,
- return_value_policy<copy_const_reference>()),
+ &markers_symbolizer::get_fill,
&markers_symbolizer::set_fill,
"Set/get the marker fill color")
.add_property("stroke",
- make_function(&markers_symbolizer::get_stroke,
- return_value_policy<copy_const_reference>()),
+ &markers_symbolizer::get_stroke,
&markers_symbolizer::set_stroke,
"Set/get the marker stroke (outline)")
- .add_property("marker_type",
- &markers_symbolizer::get_marker_type,
- &markers_symbolizer::set_marker_type,
- "Set/get the marker-type")
.add_property("placement",
&markers_symbolizer::get_marker_placement,
&markers_symbolizer::set_marker_placement,
View
38 include/mapnik/agg_helpers.hpp
@@ -129,44 +129,6 @@ void set_join_caps_aa(Stroke const& stroke_, Rasterizer & ras)
}
}
-template <typename PixelFormat>
-struct renderer_scanline_solid : private boost::noncopyable
-{
- typedef PixelFormat pixfmt_type;
- typedef typename pixfmt_type::color_type color_type;
- typedef typename pixfmt_type::row_data row_data;
- typedef agg::renderer_base<pixfmt_type> ren_base;
- typedef agg::renderer_scanline_aa_solid<ren_base> renderer;
- typedef agg::scanline_u8 scanline_type;
-
- renderer_scanline_solid()
- : renb_(),
- ren_(renb_)
- {}
-
- template <typename PF>
- void attach(PF & pf)
- {
- renb_.attach(pf);
- }
-
- void color(color_type const& c)
- {
- ren_.color(c);
- }
-
- template <typename Rasterizer>
- void render(Rasterizer & ras)
- {
- agg::render_scanlines(ras, sl_, ren_);
- sl_.reset_spans();
- }
-
- scanline_type sl_;
- ren_base renb_;
- renderer ren_;
-};
-
}
#endif //MAPNIK_AGG_HELPERS_HPP
View
4 include/mapnik/internal/dump_xml.hpp
@@ -1,6 +1,8 @@
#ifndef DUMP_XML_HPP
#define DUMP_XML_HPP
#include <mapnik/xml_node.hpp>
+namespace mapnik
+{
/* Debug dump ptree XML representation.
*/
@@ -31,5 +33,5 @@ void dump_xml(xml_node const& xml, unsigned level=0)
std::cerr << indent << "[/" << xml.name() << "]" << "\n";
}
-
+}
#endif // DUMP_XML_HPP
View
35 include/mapnik/markers_symbolizer.hpp
@@ -31,6 +31,9 @@
#include <mapnik/enumeration.hpp>
#include <mapnik/expression.hpp>
+// boost
+#include <boost/optional.hpp>
+
namespace mapnik {
// TODO - consider merging with text_symbolizer label_placement_e
@@ -42,20 +45,12 @@ enum marker_placement_enum {
DEFINE_ENUM( marker_placement_e, marker_placement_enum );
-enum marker_type_enum {
- MARKER_ARROW,
- MARKER_ELLIPSE,
- marker_type_enum_MAX
-};
-
-DEFINE_ENUM( marker_type_e, marker_type_enum );
-
struct MAPNIK_DECL markers_symbolizer :
public symbolizer_with_image, public symbolizer_base
{
public:
explicit markers_symbolizer();
- markers_symbolizer(path_expression_ptr filename);
+ markers_symbolizer(path_expression_ptr const& filename);
markers_symbolizer(markers_symbolizer const& rhs);
void set_ignore_placement(bool ignore_placement);
bool get_ignore_placement() const;
@@ -65,30 +60,26 @@ struct MAPNIK_DECL markers_symbolizer :
double get_spacing() const;
void set_max_error(double max_error);
double get_max_error() const;
- void set_fill(color fill);
- color const& get_fill() const;
- void set_width(expression_ptr width);
- expression_ptr get_width() const;
- void set_height(expression_ptr height);
- expression_ptr get_height() const;
- stroke const& get_stroke() const;
+ void set_width(expression_ptr const&width);
+ expression_ptr const& get_width() const;
+ void set_height(expression_ptr const& height);
+ expression_ptr const& get_height() const;
+ void set_fill(color const& fill);
+ boost::optional<color> get_fill() const;
void set_stroke(stroke const& stroke);
+ boost::optional<stroke> get_stroke() const;
void set_marker_placement(marker_placement_e marker_p);
marker_placement_e get_marker_placement() const;
- void set_marker_type(marker_type_e marker_p);
- marker_type_e get_marker_type() const;
-
private:
bool ignore_placement_;
bool allow_overlap_;
- color fill_;
double spacing_;
double max_error_;
expression_ptr width_;
expression_ptr height_;
- stroke stroke_;
+ boost::optional<color> fill_;
+ boost::optional<stroke> stroke_;
marker_placement_e marker_p_;
- marker_type_e marker_type_;
};
View
1 include/mapnik/xml_tree.hpp
@@ -50,6 +50,7 @@ class xml_tree
void set_filename(std::string fn);
std::string const& filename() const;
xml_node &root();
+ xml_node const& root() const;
private:
xml_node node_;
std::string file_;
View
232 src/agg/process_markers_symbolizer.cpp
@@ -49,6 +49,39 @@
namespace mapnik {
+
+template <typename Attr>
+bool push_explicit_style(Attr const& src, Attr & dst, markers_symbolizer const& sym)
+{
+ boost::optional<stroke> const& strk = sym.get_stroke();
+ boost::optional<color> const& fill = sym.get_fill();
+ if (strk || fill)
+ {
+ for(unsigned i = 0; i < src.size(); ++i)
+ {
+ mapnik::svg::path_attributes attr = src[i];
+
+ if (strk)
+ {
+ attr.stroke_width = (*strk).get_width();
+ color const& s_color = (*strk).get_color();
+ attr.stroke_color = agg::rgba(s_color.red()/255.0,s_color.green()/255.0,
+ s_color.blue()/255.0,s_color.alpha()/255.0);
+ }
+ if (fill)
+ {
+
+ color const& f_color = *fill;
+ attr.fill_color = agg::rgba(f_color.red()/255.0,f_color.green()/255.0,
+ f_color.blue()/255.0,f_color.alpha()/255.0);
+ }
+ dst.push_back(attr);
+ }
+ return true;
+ }
+ return false;
+}
+
template <typename T>
void agg_renderer<T>::process(markers_symbolizer const& sym,
mapnik::feature_impl & feature,
@@ -82,8 +115,6 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
std::string filename = path_processor_type::evaluate(*sym.get_filename(), feature);
marker_placement_e placement_method = sym.get_marker_placement();
- marker_type_e marker_type = sym.get_marker_type();
- metawriter_with_properties writer = sym.get_metawriter();
if (!filename.empty())
{
@@ -98,23 +129,25 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
}
boost::optional<path_ptr> marker = (*mark)->get_vector_data();
box2d<double> const& bbox = (*marker)->bounding_box();
- coord2d const center = bbox.center();
+ coord2d center = bbox.center();
- agg::trans_affine_translation const recenter(-center.x, -center.y);
- agg::trans_affine const marker_trans = recenter * tr;
+ agg::trans_affine_translation recenter(-center.x, -center.y);
+ agg::trans_affine marker_trans = recenter * tr;
using namespace mapnik::svg;
vertex_stl_adapter<svg_path_storage> stl_storage((*marker)->source());
svg_path_adapter svg_path(stl_storage);
+ agg::pod_bvector<path_attributes> attributes;
+ bool result = push_explicit_style( (*marker)->attributes(), attributes, sym);
+
svg_renderer<svg_path_adapter,
- agg::pod_bvector<path_attributes>,
- renderer_type,
- agg::pixfmt_rgba32 > svg_renderer(svg_path,(*marker)->attributes());
+ agg::pod_bvector<path_attributes>,
+ renderer_type,
+ agg::pixfmt_rgba32 > svg_renderer(svg_path, result ? attributes : (*marker)->attributes());
- for (unsigned i=0; i<feature.num_geometries(); ++i)
+ BOOST_FOREACH( geometry_type & geom, feature.paths())
{
- geometry_type & geom = feature.get_geometry(i);
// TODO - merge this code with point_symbolizer rendering
if (placement_method == MARKER_POINT_PLACEMENT || geom.num_points() <= 1)
{
@@ -140,8 +173,6 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
if (!sym.get_ignore_placement())
detector_->insert(transformed_bbox);
- //metawriter_with_properties writer = sym.get_metawriter();
- //if (writer.first) writer.first->add_box(extent, feature, t_, writer.second);
}
}
else
@@ -151,9 +182,9 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
path_type path(t_,clipped,prj_trans);
transformed_path_type path_transformed(path,geom_tr);
markers_placement<transformed_path_type, label_collision_detector4> placement(path_transformed, bbox, marker_trans, *detector_,
- sym.get_spacing() * scale_factor_,
- sym.get_max_error(),
- sym.get_allow_overlap());
+ sym.get_spacing() * scale_factor_,
+ sym.get_max_error(),
+ sym.get_allow_overlap());
double x, y, angle;
while (placement.get_point(x, y, angle))
{
@@ -165,184 +196,15 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
if (/* DEBUG */ 0)
{
debug_draw_box(buf, bbox*matrix, 0, 0, 0.0);
- // note: debug_draw_box(buf, extent, x, y, angle)
- // would draw a rotated box showing the proper
- // bounds of the marker, while the above will
- // draw the box used for collision detection,
- // which embraces the rotated extent but isn't
- // rotated itself
- }
- if (writer.first)
- {
- //writer.first->add_box(label_ext, feature, t_, writer.second);
- //MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: metawriter do not yet supported for line placement";
}
}
}
}
}
}
- else // FIXME: should default marker be stored in marker_cache ???
- {
- color const& fill_ = sym.get_fill();
- unsigned r = fill_.red();
- unsigned g = fill_.green();
- unsigned b = fill_.blue();
- unsigned a = fill_.alpha();
- stroke const& stroke_ = sym.get_stroke();
- color const& col = stroke_.get_color();
- double strk_width = stroke_.get_width();
- unsigned s_r=col.red();
- unsigned s_g=col.green();
- unsigned s_b=col.blue();
- unsigned s_a=col.alpha();
- double w = (boost::apply_visitor(evaluate<Feature,value_type>(feature), *(sym.get_width()))).to_double() * scale_factor_;
- double h = (boost::apply_visitor(evaluate<Feature,value_type>(feature), *(sym.get_height()))).to_double() * scale_factor_;
-
- double rx = w/2.0;
- double ry = h/2.0;
-
- arrow arrow_;
- box2d<double> extent;
-
- double dx = w + (2*strk_width);
- double dy = h + (2*strk_width);
-
- if (marker_type == MARKER_ARROW)
- {
- extent = arrow_.extent();
- }
- else
- {
- double x1 = -1 *(dx);
- double y1 = -1 *(dy);
- double x2 = dx;
- double y2 = dy;
- extent.init(x1,y1,x2,y2);
- }
-
- coord2d center = extent.center();
- agg::trans_affine_translation recenter(-center.x, -center.y);
- agg::trans_affine marker_trans = recenter * tr;
-
- double x;
- double y;
- double z=0;
-
- agg::path_storage marker;
-
- for (unsigned i=0; i<feature.num_geometries(); ++i)
- {
- geometry_type & geom = feature.get_geometry(i);
- //if (geom.num_points() <= 1) continue;
- if (placement_method == MARKER_POINT_PLACEMENT || geom.num_points() <= 1)
- {
- geom.label_position(&x,&y);
- prj_trans.backward(x,y,z);
- t_.forward(&x,&y);
- geom_tr.transform(&x,&y);
- int px = int(floor(x - 0.5 * dx));
- int py = int(floor(y - 0.5 * dy));
- box2d<double> label_ext (px, py, px + dx +1, py + dy +1);
-
- if (sym.get_allow_overlap() ||
- detector_->has_placement(label_ext))
- {
- agg::ellipse c(x, y, rx, ry);
- marker.concat_path(c);
- ras_ptr->add_path(marker);
- ren.color(agg::rgba8_pre(r, g, b, int(a*sym.get_opacity())));
- // TODO - fill with packed scanlines? agg::scanline_p8
- // and agg::renderer_outline_aa
- agg::render_scanlines(*ras_ptr, sl, ren);
-
- // outline
- if (strk_width)
- {
- ras_ptr->reset();
- agg::conv_stroke<agg::path_storage> outline(marker);
- outline.generator().width(strk_width * scale_factor_);
- ras_ptr->add_path(outline);
-
- ren.color(agg::rgba8_pre(s_r, s_g, s_b, int(s_a*stroke_.get_opacity())));
- agg::render_scanlines(*ras_ptr, sl, ren);
- }
- if (!sym.get_ignore_placement())
- detector_->insert(label_ext);
- if (writer.first) writer.first->add_box(label_ext, feature, t_, writer.second);
- }
- }
- else
- {
-
- if (marker_type == MARKER_ARROW)
- marker.concat_path(arrow_);
-
- clipped_geometry_type clipped(geom);
- clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy());
- path_type path(t_,clipped,prj_trans);
- transformed_path_type path_transformed(path,geom_tr);
- markers_placement<transformed_path_type, label_collision_detector4> placement(path_transformed, extent, marker_trans, *detector_,
- sym.get_spacing() * scale_factor_,
- sym.get_max_error(),
- sym.get_allow_overlap());
- double x_t, y_t, angle;
- while (placement.get_point(x_t, y_t, angle))
- {
- agg::trans_affine matrix;
-
- if (marker_type == MARKER_ELLIPSE)
- {
- // todo proper bbox - this is buggy
- agg::ellipse c(x_t, y_t, rx, ry);
- marker.concat_path(c);
- agg::trans_affine matrix = marker_trans;
- matrix *= agg::trans_affine_translation(-x_t,-y_t);
- matrix *= agg::trans_affine_rotation(angle);
- matrix *= agg::trans_affine_translation(x_t,y_t);
- marker.transform(matrix);
-
- }
- else
- {
- matrix = marker_trans * agg::trans_affine_rotation(angle) * agg::trans_affine_translation(x_t, y_t);
- }
-
- if (/* DEBUG */ 0)
- {
- debug_draw_box(buf, extent*matrix, 0, 0, 0.0);
- }
-
- if (writer.first)
- {
- //writer.first->add_box(label_ext, feature, t_, writer.second);
-
- MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: metawriter do not yet supported for line placement";
- }
-
- agg::conv_transform<agg::path_storage, agg::trans_affine> trans(marker, matrix);
- ras_ptr->add_path(trans);
-
- // fill
- ren.color(agg::rgba8_pre(r, g, b, int(a*sym.get_opacity())));
- agg::render_scanlines(*ras_ptr, sl, ren);
-
- // outline
- if (strk_width)
- {
- ras_ptr->reset();
- agg::conv_stroke<agg::conv_transform<agg::path_storage, agg::trans_affine> > outline(trans);
- outline.generator().width(strk_width * scale_factor_);
- ras_ptr->add_path(outline);
- ren.color(agg::rgba8_pre(s_r, s_g, s_b, int(s_a*stroke_.get_opacity())));
- agg::render_scanlines(*ras_ptr, sl, ren);
- }
- }
- }
- }
- }
}
+
template void agg_renderer<image_32>::process(markers_symbolizer const&,
mapnik::feature_impl &,
proj_transform const&);
View
1,229 src/cairo_renderer.cpp
@@ -770,871 +770,714 @@ void cairo_renderer_base::start_map_processing(Map const& map)
MAPNIK_LOG_DEBUG(cairo_renderer) << "cairo_renderer_base: Start map processing bbox=" << map.get_current_extent();
#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 6, 0)
- box2d<double> bounds = t_.forward(t_.extent());
- context_->rectangle(bounds.minx(), bounds.miny(), bounds.maxx(), bounds.maxy());
- context_->clip();
+ box2d<double> bounds = t_.forward(t_.extent());
+ context_->rectangle(bounds.minx(), bounds.miny(), bounds.maxx(), bounds.maxy());
+ context_->clip();
#else
#warning building against cairo older that 1.6.0, map clipping is disabled
#endif
- boost::optional<color> bg = m_.background();
- if (bg)
- {
- cairo_context context(context_);
- context.set_color(*bg);
- context.paint();
- }
- }
-
- template <>
- void cairo_renderer<Cairo::Context>::end_map_processing(Map const& )
+ boost::optional<color> bg = m_.background();
+ if (bg)
{
- MAPNIK_LOG_DEBUG(cairo_renderer) << "cairo_renderer_base: End map processing";
+ cairo_context context(context_);
+ context.set_color(*bg);
+ context.paint();
}
+}
- template <>
- void cairo_renderer<Cairo::Surface>::end_map_processing(Map const& )
- {
- MAPNIK_LOG_DEBUG(cairo_renderer) << "cairo_renderer_base: End map processing";
+template <>
+void cairo_renderer<Cairo::Context>::end_map_processing(Map const& )
+{
+ MAPNIK_LOG_DEBUG(cairo_renderer) << "cairo_renderer_base: End map processing";
+}
- context_->show_page();
- }
+template <>
+void cairo_renderer<Cairo::Surface>::end_map_processing(Map const& )
+{
+ MAPNIK_LOG_DEBUG(cairo_renderer) << "cairo_renderer_base: End map processing";
- void cairo_renderer_base::start_layer_processing(layer const& lay, box2d<double> const& query_extent)
- {
- MAPNIK_LOG_DEBUG(cairo_renderer) << "cairo_renderer_base: Start processing layer=" << lay.name() ;
- MAPNIK_LOG_DEBUG(cairo_renderer) << "cairo_renderer_base: -- datasource=" << lay.datasource().get();
- MAPNIK_LOG_DEBUG(cairo_renderer) << "cairo_renderer_base: -- query_extent=" << query_extent;
+ context_->show_page();
+}
- if (lay.clear_label_cache())
- {
- detector_.clear();
- }
- query_extent_ = query_extent;
- }
+void cairo_renderer_base::start_layer_processing(layer const& lay, box2d<double> const& query_extent)
+{
+ MAPNIK_LOG_DEBUG(cairo_renderer) << "cairo_renderer_base: Start processing layer=" << lay.name() ;
+ MAPNIK_LOG_DEBUG(cairo_renderer) << "cairo_renderer_base: -- datasource=" << lay.datasource().get();
+ MAPNIK_LOG_DEBUG(cairo_renderer) << "cairo_renderer_base: -- query_extent=" << query_extent;
- void cairo_renderer_base::end_layer_processing(layer const&)
+ if (lay.clear_label_cache())
{
- MAPNIK_LOG_DEBUG(cairo_renderer) << "cairo_renderer_base: End layer processing";
+ detector_.clear();
}
+ query_extent_ = query_extent;
+}
- void cairo_renderer_base::start_style_processing(feature_type_style const& st)
- {
- MAPNIK_LOG_DEBUG(cairo_renderer) << "cairo_renderer:start style processing";
- }
+void cairo_renderer_base::end_layer_processing(layer const&)
+{
+ MAPNIK_LOG_DEBUG(cairo_renderer) << "cairo_renderer_base: End layer processing";
+}
- void cairo_renderer_base::end_style_processing(feature_type_style const& st)
- {
- MAPNIK_LOG_DEBUG(cairo_renderer) << "cairo_renderer:end style processing";
- }
+void cairo_renderer_base::start_style_processing(feature_type_style const& st)
+{
+ MAPNIK_LOG_DEBUG(cairo_renderer) << "cairo_renderer:start style processing";
+}
- void cairo_renderer_base::process(polygon_symbolizer const& sym,
- mapnik::feature_impl & feature,
- proj_transform const& prj_trans)
- {
- cairo_context context(context_);
- context.set_operator(sym.comp_op());
- context.set_color(sym.get_fill(), sym.get_opacity());
+void cairo_renderer_base::end_style_processing(feature_type_style const& st)
+{
+ MAPNIK_LOG_DEBUG(cairo_renderer) << "cairo_renderer:end style processing";
+}
+
+void cairo_renderer_base::process(polygon_symbolizer const& sym,
+ mapnik::feature_impl & feature,
+ proj_transform const& prj_trans)
+{
+ cairo_context context(context_);
+ context.set_operator(sym.comp_op());
+ context.set_color(sym.get_fill(), sym.get_opacity());
- agg::trans_affine tr;
- evaluate_transform(tr, feature, sym.get_transform());
+ agg::trans_affine tr;
+ evaluate_transform(tr, feature, sym.get_transform());
- typedef boost::mpl::vector<clip_poly_tag,transform_tag,affine_transform_tag,smooth_tag> conv_types;
- vertex_converter<box2d<double>, cairo_context, polygon_symbolizer,
- CoordTransform, proj_transform, agg::trans_affine, conv_types>
- converter(query_extent_,context,sym,t_,prj_trans,tr,1.0);
+ typedef boost::mpl::vector<clip_poly_tag,transform_tag,affine_transform_tag,smooth_tag> conv_types;
+ vertex_converter<box2d<double>, cairo_context, polygon_symbolizer,
+ CoordTransform, proj_transform, agg::trans_affine, conv_types>
+ converter(query_extent_,context,sym,t_,prj_trans,tr,1.0);
- if (sym.clip()) converter.set<clip_poly_tag>(); //optional clip (default: true)
- converter.set<transform_tag>(); //always transform
- converter.set<affine_transform_tag>();
- if (sym.smooth() > 0.0) converter.set<smooth_tag>(); // optional smooth converter
+ if (sym.clip()) converter.set<clip_poly_tag>(); //optional clip (default: true)
+ converter.set<transform_tag>(); //always transform
+ converter.set<affine_transform_tag>();
+ 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())
+ {
+ if (geom.num_points() > 2)
{
- if (geom.num_points() > 2)
- {
- converter.apply(geom);
- }
+ converter.apply(geom);
}
- // fill polygon
- context.fill();
}
+ // fill polygon
+ context.fill();
+}
- void cairo_renderer_base::process(building_symbolizer const& sym,
- mapnik::feature_impl & feature,
- proj_transform const& prj_trans)
+void cairo_renderer_base::process(building_symbolizer const& sym,
+ mapnik::feature_impl & feature,
+ proj_transform const& prj_trans)
+{
+ typedef coord_transform<CoordTransform,geometry_type> path_type;
+
+ cairo_context context(context_);
+ context.set_operator(sym.comp_op());
+ color const& fill = sym.get_fill();
+ double height = 0.0;
+ expression_ptr height_expr = sym.height();
+ if (height_expr)
{
- typedef coord_transform<CoordTransform,geometry_type> path_type;
+ value_type result = boost::apply_visitor(evaluate<Feature,value_type>(feature), *height_expr);
+ height = result.to_double(); //scale_factor is always 1.0 atm
+ }
- cairo_context context(context_);
- context.set_operator(sym.comp_op());
- color const& fill = sym.get_fill();
- double height = 0.0;
- expression_ptr height_expr = sym.height();
- if (height_expr)
- {
- value_type result = boost::apply_visitor(evaluate<Feature,value_type>(feature), *height_expr);
- height = result.to_double(); //scale_factor is always 1.0 atm
- }
+ for (unsigned i = 0; i < feature.num_geometries(); ++i)
+ {
+ geometry_type const& geom = feature.get_geometry(i);
- for (unsigned i = 0; i < feature.num_geometries(); ++i)
+ if (geom.num_points() > 2)
{
- geometry_type const& geom = feature.get_geometry(i);
+ boost::scoped_ptr<geometry_type> frame(new geometry_type(LineString));
+ boost::scoped_ptr<geometry_type> roof(new geometry_type(Polygon));
+ std::deque<segment_t> face_segments;
+ double x0(0);
+ double y0(0);
- if (geom.num_points() > 2)
+ geom.rewind(0);
+ unsigned cm = geom.vertex(&x0, &y0);
+
+ for (unsigned j = 1; j < geom.num_points(); ++j)
{
- boost::scoped_ptr<geometry_type> frame(new geometry_type(LineString));
- boost::scoped_ptr<geometry_type> roof(new geometry_type(Polygon));
- std::deque<segment_t> face_segments;
- double x0(0);
- double y0(0);
+ double x=0;
+ double y=0;
- geom.rewind(0);
- unsigned cm = geom.vertex(&x0, &y0);
+ cm = geom.vertex(&x,&y);
- for (unsigned j = 1; j < geom.num_points(); ++j)
+ if (cm == SEG_MOVETO)
+ {
+ frame->move_to(x,y);
+ }
+ else if (cm == SEG_LINETO)
{
- double x=0;
- double y=0;
+ frame->line_to(x,y);
+ }
- cm = geom.vertex(&x,&y);
+ if (j != 0)
+ {
+ face_segments.push_back(segment_t(x0, y0, x, y));
+ }
- if (cm == SEG_MOVETO)
- {
- frame->move_to(x,y);
- }
- else if (cm == SEG_LINETO)
- {
- frame->line_to(x,y);
- }
+ x0 = x;
+ y0 = y;
+ }
- if (j != 0)
- {
- face_segments.push_back(segment_t(x0, y0, x, y));
- }
+ std::sort(face_segments.begin(), face_segments.end(), y_order);
+ std::deque<segment_t>::const_iterator itr = face_segments.begin();
+ for (; itr != face_segments.end(); ++itr)
+ {
+ boost::scoped_ptr<geometry_type> faces(new geometry_type(Polygon));
- x0 = x;
- y0 = y;
- }
+ faces->move_to(itr->get<0>(), itr->get<1>());
+ faces->line_to(itr->get<2>(), itr->get<3>());
+ faces->line_to(itr->get<2>(), itr->get<3>() + height);
+ faces->line_to(itr->get<0>(), itr->get<1>() + height);
- std::sort(face_segments.begin(), face_segments.end(), y_order);
- std::deque<segment_t>::const_iterator itr = face_segments.begin();
- for (; itr != face_segments.end(); ++itr)
- {
- boost::scoped_ptr<geometry_type> faces(new geometry_type(Polygon));
+ path_type faces_path(t_, *faces, prj_trans);
+ context.set_color(int(fill.red() * 0.8), int(fill.green() * 0.8),
+ int(fill.blue() * 0.8), fill.alpha() * sym.get_opacity() / 255.0);
+ context.add_path(faces_path);
+ context.fill();
- faces->move_to(itr->get<0>(), itr->get<1>());
- faces->line_to(itr->get<2>(), itr->get<3>());
- faces->line_to(itr->get<2>(), itr->get<3>() + height);
- faces->line_to(itr->get<0>(), itr->get<1>() + height);
+ frame->move_to(itr->get<0>(), itr->get<1>());
+ frame->line_to(itr->get<0>(), itr->get<1>() + height);
+ }
- path_type faces_path(t_, *faces, prj_trans);
- context.set_color(int(fill.red() * 0.8), int(fill.green() * 0.8),
- int(fill.blue() * 0.8), fill.alpha() * sym.get_opacity() / 255.0);
- context.add_path(faces_path);
- context.fill();
+ geom.rewind(0);
+ for (unsigned j = 0; j < geom.num_points(); ++j)
+ {
+ double x, y;
+ unsigned cm = geom.vertex(&x, &y);
- frame->move_to(itr->get<0>(), itr->get<1>());
- frame->line_to(itr->get<0>(), itr->get<1>() + height);
+ if (cm == SEG_MOVETO)
+ {
+ frame->move_to(x, y + height);
+ roof->move_to(x, y + height);
}
-
- geom.rewind(0);
- for (unsigned j = 0; j < geom.num_points(); ++j)
+ else if (cm == SEG_LINETO)
{
- double x, y;
- unsigned cm = geom.vertex(&x, &y);
-
- if (cm == SEG_MOVETO)
- {
- frame->move_to(x, y + height);
- roof->move_to(x, y + height);
- }
- else if (cm == SEG_LINETO)
- {
- frame->line_to(x, y + height);
- roof->line_to(x, y + height);
- }
+ frame->line_to(x, y + height);
+ roof->line_to(x, y + height);
}
+ }
- path_type path(t_, *frame, prj_trans);
- context.set_color(fill.red()*0.8, fill.green()*0.8, fill.blue()*0.8, fill.alpha() * sym.get_opacity() / 255.0);
- context.add_path(path);
- context.stroke();
+ path_type path(t_, *frame, prj_trans);
+ context.set_color(fill.red()*0.8, fill.green()*0.8, fill.blue()*0.8, fill.alpha() * sym.get_opacity() / 255.0);
+ context.add_path(path);
+ context.stroke();
- path_type roof_path(t_, *roof, prj_trans);
- context.set_color(fill, sym.get_opacity());
- context.add_path(roof_path);
- context.fill();
- }
+ path_type roof_path(t_, *roof, prj_trans);
+ context.set_color(fill, sym.get_opacity());
+ context.add_path(roof_path);
+ context.fill();
}
}
+}
+
+void cairo_renderer_base::process(line_symbolizer const& sym,
+ mapnik::feature_impl & feature,
+ proj_transform const& prj_trans)
+{
+ cairo_context context(context_);
+ mapnik::stroke const& stroke_ = sym.get_stroke();
+ context.set_operator(sym.comp_op());
- void cairo_renderer_base::process(line_symbolizer const& sym,
- mapnik::feature_impl & feature,
- proj_transform const& prj_trans)
+ context.set_color(stroke_.get_color(), stroke_.get_opacity());
+ context.set_line_join(stroke_.get_line_join());
+ context.set_line_cap(stroke_.get_line_cap());
+ context.set_miter_limit(stroke_.get_miterlimit());
+ context.set_line_width(stroke_.get_width());
+ if (stroke_.has_dash())
{
- cairo_context context(context_);
- mapnik::stroke const& stroke_ = sym.get_stroke();
- context.set_operator(sym.comp_op());
-
- context.set_color(stroke_.get_color(), stroke_.get_opacity());
- context.set_line_join(stroke_.get_line_join());
- context.set_line_cap(stroke_.get_line_cap());
- context.set_miter_limit(4.0);
- context.set_line_width(stroke_.get_width());
- if (stroke_.has_dash())
- {
- context.set_dash(stroke_.get_dash_array());
- }
+ context.set_dash(stroke_.get_dash_array());
+ }
- agg::trans_affine tr;
- evaluate_transform(tr, feature, sym.get_transform());
+ agg::trans_affine tr;
+ evaluate_transform(tr, feature, sym.get_transform());
- box2d<double> ext = query_extent_ * 1.1;
- typedef boost::mpl::vector<clip_line_tag,transform_tag, offset_transform_tag, affine_transform_tag, smooth_tag> conv_types;
- vertex_converter<box2d<double>, cairo_context, line_symbolizer,
- CoordTransform, proj_transform, agg::trans_affine, conv_types>
- converter(ext,context,sym,t_,prj_trans,tr,1.0);
+ box2d<double> ext = query_extent_ * 1.1;
+ typedef boost::mpl::vector<clip_line_tag,transform_tag, offset_transform_tag, affine_transform_tag, smooth_tag> conv_types;
+ vertex_converter<box2d<double>, cairo_context, line_symbolizer,
+ CoordTransform, proj_transform, agg::trans_affine, conv_types>
+ converter(ext,context,sym,t_,prj_trans,tr,1.0);
- if (sym.clip()) converter.set<clip_line_tag>(); // optional clip (default: true)
- converter.set<transform_tag>(); // always transform
+ if (sym.clip()) converter.set<clip_line_tag>(); // optional clip (default: true)
+ converter.set<transform_tag>(); // always transform
- if (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 (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
- BOOST_FOREACH( geometry_type & geom, feature.paths())
+ BOOST_FOREACH( geometry_type & geom, feature.paths())
+ {
+ if (geom.num_points() > 1)
{
- if (geom.num_points() > 1)
- {
- converter.apply(geom);
- }
+ converter.apply(geom);
}
- // stroke
- context.stroke();
}
+ // stroke
+ context.stroke();
+}
+
+void cairo_renderer_base::render_marker(pixel_position const& pos, marker const& marker, const agg::trans_affine & tr, double opacity, bool recenter)
- void cairo_renderer_base::render_marker(pixel_position const& pos, marker const& marker, const agg::trans_affine & tr, double opacity, bool recenter)
+{
+ cairo_context context(context_);
+ if (marker.is_vector())
{
- cairo_context context(context_);
+ box2d<double> bbox;
+ bbox = (*marker.get_vector_data())->bounding_box();
+
+ agg::trans_affine mtx = tr;
- if (marker.is_vector())
+ if (recenter)
{
- box2d<double> bbox;
- bbox = (*marker.get_vector_data())->bounding_box();
+ coord<double,2> c = bbox.center();
+ // center the svg marker on '0,0'
+ mtx = agg::trans_affine_translation(-c.x,-c.y);
+ // apply symbol transformation to get to map space
+ mtx *= tr;
+ // render the marker at the center of the marker box
+ mtx.translate(pos.x+0.5 * marker.width(), pos.y+0.5 * marker.height());
+ }
- agg::trans_affine mtx = tr;
+ typedef coord_transform<CoordTransform,geometry_type> path_type;
+ agg::trans_affine transform;
+ mapnik::path_ptr vmarker = *marker.get_vector_data();
+ using namespace mapnik::svg;
+ agg::pod_bvector<path_attributes> const & attributes_ = vmarker->attributes();
+ for(unsigned i = 0; i < attributes_.size(); ++i)
+ {
+ mapnik::svg::path_attributes const& attr = attributes_[i];
+ if (!attr.visibility_flag)
+ continue;
- if (recenter)
- {
- coord<double,2> c = bbox.center();
- // center the svg marker on '0,0'
- mtx = agg::trans_affine_translation(-c.x,-c.y);
- // apply symbol transformation to get to map space
- mtx *= tr;
- // render the marker at the center of the marker box
- mtx.translate(pos.x+0.5 * marker.width(), pos.y+0.5 * marker.height());
- }
+ context.save();
- typedef coord_transform<CoordTransform,geometry_type> path_type;
- agg::trans_affine transform;
- mapnik::path_ptr vmarker = *marker.get_vector_data();
- using namespace mapnik::svg;
- agg::pod_bvector<path_attributes> const & attributes_ = vmarker->attributes();
- for(unsigned i = 0; i < attributes_.size(); ++i)
- {
- mapnik::svg::path_attributes const& attr = attributes_[i];
- if (!attr.visibility_flag)
- continue;
+ transform = attr.transform;
+ transform *= mtx;
- context.save();
+ // TODO - this 'is_valid' check is not used in the AGG renderer and also
+ // appears to lead to bogus results with
+ // tests/data/good_maps/markers_symbolizer_lines_file.xml
+ if (/*transform.is_valid() && */ !transform.is_identity())
+ {
+ double m[6];
+ transform.store_to(m);
+ context.transform(Cairo::Matrix(m[0],m[1],m[2],m[3],m[4],m[5]));
+ }
- transform = attr.transform;
- transform *= mtx;
+ vertex_stl_adapter<svg_path_storage> stl_storage(vmarker->source());
+ svg_path_adapter svg_path(stl_storage);
- // TODO - this 'is_valid' check is not used in the AGG renderer and also
- // appears to lead to bogus results with
- // tests/data/good_maps/markers_symbolizer_lines_file.xml
- if (/*transform.is_valid() && */ !transform.is_identity())
+ if (attr.fill_flag || attr.fill_gradient.get_gradient_type() != NO_GRADIENT)
+ {
+ context.add_agg_path(svg_path,attr.index);
+ if (attr.even_odd_flag)
{
- double m[6];
- transform.store_to(m);
- context.transform(Cairo::Matrix(m[0],m[1],m[2],m[3],m[4],m[5]));
+ context.set_fill_rule(Cairo::FILL_RULE_EVEN_ODD);
}
-
- vertex_stl_adapter<svg_path_storage> stl_storage(vmarker->source());
- svg_path_adapter svg_path(stl_storage);
-
- if (attr.fill_flag || attr.fill_gradient.get_gradient_type() != NO_GRADIENT)
+ else
{
- context.add_agg_path(svg_path,attr.index);
- if (attr.even_odd_flag)
- {
- context.set_fill_rule(Cairo::FILL_RULE_EVEN_ODD);
- }
- else
- {
- context.set_fill_rule(Cairo::FILL_RULE_WINDING);
- }
- if(attr.fill_gradient.get_gradient_type() != NO_GRADIENT)
- {
- cairo_gradient g(attr.fill_gradient,attr.opacity*opacity);
-
- context.set_gradient(g,bbox);
- context.fill();
- }
- else if(attr.fill_flag)
- {
- double fill_opacity = attr.opacity * opacity * attr.fill_color.opacity();
- context.set_color(attr.fill_color.r,attr.fill_color.g,attr.fill_color.b, fill_opacity);
- context.fill();
- }
+ context.set_fill_rule(Cairo::FILL_RULE_WINDING);
}
+ if(attr.fill_gradient.get_gradient_type() != NO_GRADIENT)
+ {
+ cairo_gradient g(attr.fill_gradient,attr.opacity*opacity);
- if (attr.stroke_gradient.get_gradient_type() != NO_GRADIENT || attr.stroke_flag)
+ context.set_gradient(g,bbox);
+ context.fill();
+ }
+ else if(attr.fill_flag)
{
- context.add_agg_path(svg_path,attr.index);
- if(attr.stroke_gradient.get_gradient_type() != NO_GRADIENT)
- {
- context.set_line_width(attr.stroke_width);
- context.set_line_cap(line_cap_enum(attr.line_cap));
- context.set_line_join(line_join_enum(attr.line_join));
- context.set_miter_limit(attr.miter_limit);
- cairo_gradient g(attr.stroke_gradient,attr.opacity*opacity);
- context.set_gradient(g,bbox);
- context.stroke();
- }
- else if (attr.stroke_flag)
- {
- double stroke_opacity = attr.opacity * opacity * attr.stroke_color.opacity();
- context.set_color(attr.stroke_color.r,attr.stroke_color.g,attr.stroke_color.b, stroke_opacity);
- context.set_line_width(attr.stroke_width);
- context.set_line_cap(line_cap_enum(attr.line_cap));
- context.set_line_join(line_join_enum(attr.line_join));
- context.set_miter_limit(attr.miter_limit);
- context.stroke();
- }
+ double fill_opacity = attr.opacity * opacity * attr.fill_color.opacity();
+ context.set_color(attr.fill_color.r,attr.fill_color.g,attr.fill_color.b, fill_opacity);
+ context.fill();
}
+ }
- context.restore();
+ if (attr.stroke_gradient.get_gradient_type() != NO_GRADIENT || attr.stroke_flag)
+ {
+ context.add_agg_path(svg_path,attr.index);
+ if(attr.stroke_gradient.get_gradient_type() != NO_GRADIENT)
+ {
+ context.set_line_width(attr.stroke_width);
+ context.set_line_cap(line_cap_enum(attr.line_cap));
+ context.set_line_join(line_join_enum(attr.line_join));
+ context.set_miter_limit(attr.miter_limit);
+ cairo_gradient g(attr.stroke_gradient,attr.opacity*opacity);
+ context.set_gradient(g,bbox);
+ context.stroke();
+ }
+ else if (attr.stroke_flag)
+ {
+ double stroke_opacity = attr.opacity * opacity * attr.stroke_color.opacity();
+ context.set_color(attr.stroke_color.r,attr.stroke_color.g,attr.stroke_color.b, stroke_opacity);
+ context.set_line_width(attr.stroke_width);
+ context.set_line_cap(line_cap_enum(attr.line_cap));
+ context.set_line_join(line_join_enum(attr.line_join));
+ context.set_miter_limit(attr.miter_limit);
+ context.stroke();
+ }
}
- }
- else if (marker.is_bitmap())
- {
- context.add_image(pos.x, pos.y, **marker.get_bitmap_data(), opacity);
+
+ context.restore();
}
}
-
- void cairo_renderer_base::process(point_symbolizer const& sym,
- mapnik::feature_impl & feature,
- proj_transform const& prj_trans)
+ else if (marker.is_bitmap())
{
- std::string filename = path_processor_type::evaluate( *sym.get_filename(), feature);
+ context.add_image(pos.x, pos.y, **marker.get_bitmap_data(), opacity);
+ }
+}
- boost::optional<marker_ptr> marker;
- if ( !filename.empty() )
- {
- marker = marker_cache::instance()->find(filename, true);
- }
- else
- {
- marker.reset(boost::make_shared<mapnik::marker>());
- }
+void cairo_renderer_base::process(point_symbolizer const& sym,
+ mapnik::feature_impl & feature,
+ proj_transform const& prj_trans)
+{
+ std::string filename = path_processor_type::evaluate( *sym.get_filename(), feature);
- agg::trans_affine mtx;
- evaluate_transform(mtx, feature, sym.get_image_transform());
+ boost::optional<marker_ptr> marker;
+ if ( !filename.empty() )
+ {
+ marker = marker_cache::instance()->find(filename, true);
+ }
+ else
+ {
+ marker.reset(boost::make_shared<mapnik::marker>());
+ }
- if (marker)
+ agg::trans_affine mtx;
+ evaluate_transform(mtx, feature, sym.get_image_transform());
+
+ if (marker)
+ {
+ for (unsigned i = 0; i < feature.num_geometries(); ++i)
{
- for (unsigned i = 0; i < feature.num_geometries(); ++i)
- {
- geometry_type const& geom = feature.get_geometry(i);
- double x;
- double y;
- double z = 0;
+ geometry_type const& geom = feature.get_geometry(i);
+ double x;
+ double y;
+ double z = 0;
- if (sym.get_point_placement() == CENTROID_POINT_PLACEMENT)
- geom.label_position(&x, &y);
- else
- geom.label_interior_position(&x, &y);
+ if (sym.get_point_placement() == CENTROID_POINT_PLACEMENT)
+ geom.label_position(&x, &y);
+ else
+ geom.label_interior_position(&x, &y);
- prj_trans.backward(x, y, z);
- t_.forward(&x, &y);
+ prj_trans.backward(x, y, z);
+ t_.forward(&x, &y);
- int w = (*marker)->width();
- int h = (*marker)->height();
+ int w = (*marker)->width();
+ int h = (*marker)->height();
- int px = int(floor(x - 0.5 * w));
- int py = int(floor(y - 0.5 * h));
- box2d<double> label_ext (px, py, px + w, py + h);
- if (sym.get_allow_overlap() ||
- detector_.has_placement(label_ext))
- {
- render_marker(pixel_position(px,py),**marker, mtx, sym.get_opacity());
+ int px = int(floor(x - 0.5 * w));
+ int py = int(floor(y - 0.5 * h));
+ box2d<double> label_ext (px, py, px + w, py + h);
+ if (sym.get_allow_overlap() ||
+ detector_.has_placement(label_ext))
+ {
+ render_marker(pixel_position(px,py),**marker, mtx, sym.get_opacity());
- if (!sym.get_ignore_placement())
- detector_.insert(label_ext);
- metawriter_with_properties writer = sym.get_metawriter();
- if (writer.first)
- {
- writer.first->add_box(label_ext, feature, t_, writer.second);
- }
- }
+ if (!sym.get_ignore_placement())
+ detector_.insert(label_ext);
}
}
}
+}
- void cairo_renderer_base::process(shield_symbolizer const& sym,
- mapnik::feature_impl & feature,
- proj_transform const& prj_trans)
- {
- shield_symbolizer_helper<face_manager<freetype_engine>,
- label_collision_detector4> helper(
- sym, feature, prj_trans,
- detector_.extent().width(), detector_.extent().height(),
- 1.0 /*scale_factor*/,
- t_, font_manager_, detector_, query_extent_);
- cairo_context context(context_);
- context.set_operator(sym.comp_op());
-
- while (helper.next())
+void cairo_renderer_base::process(shield_symbolizer const& sym,
+ mapnik::feature_impl & feature,
+ proj_transform const& prj_trans)
+{
+ shield_symbolizer_helper<face_manager<freetype_engine>,
+ label_collision_detector4> helper(
+ sym, feature, prj_trans,
+ detector_.extent().width(), detector_.extent().height(),
+ 1.0 /*scale_factor*/,
+ t_, font_manager_, detector_, query_extent_);
+ cairo_context context(context_);
+ context.set_operator(sym.comp_op());
+
+ while (helper.next())
+ {
+ placements_type &placements = helper.placements();
+ for (unsigned int ii = 0; ii < placements.size(); ++ii)
{
- placements_type &placements = helper.placements();
- for (unsigned int ii = 0; ii < placements.size(); ++ii)
- {
- pixel_position marker_pos = helper.get_marker_position(placements[ii]);
- render_marker(marker_pos,
- helper.get_marker(), helper.get_image_transform(),
- sym.get_opacity());
- context.add_text(placements[ii], face_manager_, font_manager_);
- }
+ pixel_position marker_pos = helper.get_marker_position(placements[ii]);
+ render_marker(marker_pos,
+ helper.get_marker(), helper.get_image_transform(),
+ sym.get_opacity());
+ context.add_text(placements[ii], face_manager_, font_manager_);
}
}
+}
- void cairo_renderer_base::process(line_pattern_symbolizer const& sym,
- mapnik::feature_impl & feature,
- proj_transform const& prj_trans)
- {
- typedef agg::conv_clip_polyline<geometry_type> clipped_geometry_type;
- typedef coord_transform<CoordTransform,clipped_geometry_type> path_type;
+void cairo_renderer_base::process(line_pattern_symbolizer const& sym,
+ mapnik::feature_impl & feature,
+ proj_transform const& prj_trans)
+{
+ typedef agg::conv_clip_polyline<geometry_type> clipped_geometry_type;
+ typedef coord_transform<CoordTransform,clipped_geometry_type> path_type;
- std::string filename = path_processor_type::evaluate( *sym.get_filename(), feature);
- boost::optional<mapnik::marker_ptr> marker = mapnik::marker_cache::instance()->find(filename,true);
- if (!marker && !(*marker)->is_bitmap()) return;
+ std::string filename = path_processor_type::evaluate( *sym.get_filename(), feature);
+ boost::optional<mapnik::marker_ptr> marker = mapnik::marker_cache::instance()->find(filename,true);
+ if (!marker && !(*marker)->is_bitmap()) return;
- unsigned width((*marker)->width());
- unsigned height((*marker)->height());
+ unsigned width((*marker)->width());
+ unsigned height((*marker)->height());
- cairo_context context(context_);
- context.set_operator(sym.comp_op());
- cairo_pattern pattern(**((*marker)->get_bitmap_data()));
+ cairo_context context(context_);
+ context.set_operator(sym.comp_op());
+ cairo_pattern pattern(**((*marker)->get_bitmap_data()));
- pattern.set_extend(Cairo::EXTEND_REPEAT);
- pattern.set_filter(Cairo::FILTER_BILINEAR);
- context.set_line_width(height);
+ pattern.set_extend(Cairo::EXTEND_REPEAT);
+ pattern.set_filter(Cairo::FILTER_BILINEAR);
+ context.set_line_width(height);
- for (unsigned i = 0; i < feature.num_geometries(); ++i)
+ for (unsigned i = 0; i < feature.num_geometries(); ++i)
+ {
+ geometry_type & geom = feature.get_geometry(i);
+
+ if (geom.num_points() > 1)
{
- geometry_type & geom = feature.get_geometry(i);
+ clipped_geometry_type clipped(geom);
+ clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy());
+ path_type path(t_,clipped,prj_trans);
- if (geom.num_points() > 1)
- {
- clipped_geometry_type clipped(geom);
- clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy());
- path_type path(t_,clipped,prj_trans);
+ double length(0);
+ double x0(0), y0(0);
+ double x, y;
- double length(0);
- double x0(0), y0(0);
- double x, y;
-
- for (unsigned cm = path.vertex(&x, &y); cm != SEG_END; cm = path.vertex(&x, &y))
+ for (unsigned cm = path.vertex(&x, &y); cm != SEG_END; cm = path.vertex(&x, &y))
+ {
+ if (cm == SEG_MOVETO)
{
- if (cm == SEG_MOVETO)
- {
- length = 0.0;
- }
- else if (cm == SEG_LINETO)
- {
- double dx = x - x0;
- double dy = y - y0;
- double angle = atan2(dy, dx);
- double offset = fmod(length, width);
-
- Cairo::Matrix matrix;
- cairo_matrix_init_identity(&matrix);
- cairo_matrix_translate(&matrix,x0,y0);
- cairo_matrix_rotate(&matrix,angle);
- cairo_matrix_translate(&matrix,-offset,0.5*height);
- cairo_matrix_invert(&matrix);
+ length = 0.0;
+ }
+ else if (cm == SEG_LINETO)
+ {
+ double dx = x - x0;
+ double dy = y - y0;
+ double angle = atan2(dy, dx);
+ double offset = fmod(length, width);
- pattern.set_matrix(matrix);
+ Cairo::Matrix matrix;
+ cairo_matrix_init_identity(&matrix);
+ cairo_matrix_translate(&matrix,x0,y0);
+ cairo_matrix_rotate(&matrix,angle);
+ cairo_matrix_translate(&matrix,-offset,0.5*height);
+ cairo_matrix_invert(&matrix);
- context.set_pattern(pattern);
+ pattern.set_matrix(matrix);
- context.move_to(x0, y0);
- context.line_to(x, y);
- context.stroke();
+ context.set_pattern(pattern);
- length = length + hypot(x - x0, y - y0);
- }
+ context.move_to(x0, y0);
+ context.line_to(x, y);
+ context.stroke();
- x0 = x;
- y0 = y;
+ length = length + hypot(x - x0, y - y0);
}
+
+ x0 = x;
+ y0 = y;
}
}
}
+}
- void cairo_renderer_base::process(polygon_pattern_symbolizer const& sym,
- mapnik::feature_impl & feature,
- proj_transform const& prj_trans)
- {
- cairo_context context(context_);
- context.set_operator(sym.comp_op());
+void cairo_renderer_base::process(polygon_pattern_symbolizer const& sym,
+ mapnik::feature_impl & feature,
+ proj_transform const& prj_trans)
+{
+ cairo_context context(context_);
+ context.set_operator(sym.comp_op());
- std::string filename = path_processor_type::evaluate( *sym.get_filename(), feature);
- boost::optional<mapnik::marker_ptr> marker = mapnik::marker_cache::instance()->find(filename,true);
- if (!marker && !(*marker)->is_bitmap()) return;
+ std::string filename = path_processor_type::evaluate( *sym.get_filename(), feature);
+ boost::optional<mapnik::marker_ptr> marker = mapnik::marker_cache::instance()->find(filename,true);
+ if (!marker && !(*marker)->is_bitmap()) return;
- cairo_pattern pattern(**((*marker)->get_bitmap_data()));
+ cairo_pattern pattern(**((*marker)->get_bitmap_data()));
- pattern.set_extend(Cairo::EXTEND_REPEAT);
+ pattern.set_extend(Cairo::EXTEND_REPEAT);
- context.set_pattern(pattern);
+ context.set_pattern(pattern);
- agg::trans_affine tr;
- evaluate_transform(tr, feature, sym.get_transform());
+ agg::trans_affine tr;
+ evaluate_transform(tr, feature, sym.get_transform());
- typedef boost::mpl::vector<clip_poly_tag,transform_tag,affine_transform_tag,smooth_tag> conv_types;
- vertex_converter<box2d<double>, cairo_context, polygon_pattern_symbolizer,
- CoordTransform, proj_transform, agg::trans_affine, conv_types>
- converter(query_extent_,context,sym,t_,prj_trans,tr,1.0);
+ typedef boost::mpl::vector<clip_poly_tag,transform_tag,affine_transform_tag,smooth_tag> conv_types;
+ vertex_converter<box2d<double>, cairo_context, polygon_pattern_symbolizer,
+ CoordTransform, proj_transform, agg::trans_affine, conv_types>
+ converter(query_extent_,context,sym,t_,prj_trans,tr,1.0);
- if (sym.clip()) converter.set<clip_poly_tag>(); //optional clip (default: true)
- converter.set<transform_tag>(); //always transform
- converter.set<affine_transform_tag>();
- if (sym.smooth() > 0.0) converter.set<smooth_tag>(); // optional smooth converter
+ if (sym.clip()) converter.set<clip_poly_tag>(); //optional clip (default: true)
+ converter.set<transform_tag>(); //always transform
+ converter.set<affine_transform_tag>();
+ 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())
+ {
+ if (geom.num_points() > 2)
{
- if (geom.num_points() > 2)
- {
- converter.apply(geom);
- }
+ converter.apply(geom);
}
-
- // fill polygon
- context.fill();
}
- void cairo_renderer_base::process(raster_symbolizer const& sym,
- mapnik::feature_impl & feature,
- proj_transform const& prj_trans)
- {
- raster_ptr const& source = feature.get_raster();
- if (source)
+ // fill polygon
+ context.fill();
+}
+
+void cairo_renderer_base::process(raster_symbolizer const& sym,
+ mapnik::feature_impl & feature,
+ proj_transform const& prj_trans)
+{
+ raster_ptr const& source = feature.get_raster();
+ if (source)
+ {
+ // If there's a colorizer defined, use it to color the raster in-place
+ raster_colorizer_ptr colorizer = sym.get_colorizer();
+ if (colorizer)
+ colorizer->colorize(source,feature);
+
+ box2d<double> target_ext = box2d<double>(source->ext_);
+ prj_trans.backward(target_ext, PROJ_ENVELOPE_POINTS);
+
+ box2d<double> ext=t_.forward(target_ext);
+ int start_x = (int)ext.minx();
+ int start_y = (int)ext.miny();
+ int end_x = (int)ceil(ext.maxx());
+ int end_y = (int)ceil(ext.maxy());
+ int raster_width = end_x - start_x;
+ int raster_height = end_y - start_y;
+ double err_offs_x = ext.minx() - start_x;
+ double err_offs_y = ext.miny() - start_y;
+
+ if (raster_width > 0 && raster_height > 0)
{
- // If there's a colorizer defined, use it to color the raster in-place
- raster_colorizer_ptr colorizer = sym.get_colorizer();
- if (colorizer)
- colorizer->colorize(source,feature);
-
- box2d<double> target_ext = box2d<double>(source->ext_);
- prj_trans.backward(target_ext, PROJ_ENVELOPE_POINTS);
-
- box2d<double> ext=t_.forward(target_ext);
- int start_x = (int)ext.minx();
- int start_y = (int)ext.miny();
- int end_x = (int)ceil(ext.maxx());
- int end_y = (int)ceil(ext.maxy());
- int raster_width = end_x - start_x;
- int raster_height = end_y - start_y;
- double err_offs_x = ext.minx() - start_x;
- double err_offs_y = ext.miny() - start_y;
-
- if (raster_width > 0 && raster_height > 0)
- {
- double scale_factor = ext.width() / source->data_.width();
- image_data_32 target_data(raster_width,raster_height);
- raster target(target_ext, target_data);
-
- reproject_raster(target, *source, prj_trans, err_offs_x, err_offs_y,
- sym.get_mesh_size(),
- sym.calculate_filter_factor(),
- scale_factor,
- sym.get_scaling());
-
- cairo_context context(context_);
- context.set_operator(sym.comp_op());
- //TODO -- support for advanced image merging
- context.add_image(start_x, start_y, target.data_, sym.get_opacity());
- }
+ double scale_factor = ext.width() / source->data_.width();
+ image_data_32 target_data(raster_width,raster_height);
+ raster target(target_ext, target_data);
+
+ reproject_raster(target, *source, prj_trans, err_offs_x, err_offs_y,
+ sym.get_mesh_size(),
+ sym.calculate_filter_factor(),
+ scale_factor,
+ sym.get_scaling());
+
+ cairo_context context(context_);
+ context.set_operator(sym.comp_op());
+ //TODO -- support for advanced image merging
+ context.add_image(start_x, start_y, target.data_, sym.get_opacity());
}
}
+}
- void cairo_renderer_base::process(markers_symbolizer const& sym,
- mapnik::feature_impl & feature,
- proj_transform const& prj_trans)
- {
- cairo_context context(context_);
- context.set_operator(sym.comp_op());
- double scale_factor_ = 1;
-
- typedef agg::conv_clip_polyline<geometry_type> clipped_geometry_type;
- typedef coord_transform<CoordTransform,clipped_geometry_type> path_type;
+void cairo_renderer_base::process(markers_symbolizer const& sym,
+ mapnik::feature_impl & feature,
+ proj_transform const& prj_trans)
+{
+ cairo_context context(context_);
+ context.set_operator(sym.comp_op());
+ double scale_factor_ = 1;
- agg::trans_affine tr;
- evaluate_transform(tr, feature, sym.get_image_transform());
+ typedef agg::conv_clip_polyline<geometry_type> clipped_geometry_type;
+ typedef coord_transform<CoordTransform,clipped_geometry_type> path_type;
- // TODO - use this?
- //tr = agg::trans_affine_scaling(scale_factor_) * tr;
- std::string filename = path_processor_type::evaluate(*sym.get_filename(), feature);
- marker_placement_e placement_method = sym.get_marker_placement();
- marker_type_e marker_type = sym.get_marker_type();
- metawriter_with_properties writer = sym.get_metawriter();
+ agg::trans_affine tr;
+ evaluate_transform(tr, feature, sym.get_image_transform());
+
+ tr = agg::trans_affine_scaling(scale_factor_) * tr;
+ std::string filename = path_processor_type::evaluate(*sym.get_filename(), feature);
+ marker_placement_e placement_method = sym.get_marker_placement();
- if (!filename.empty())
+ if (!filename.empty())
+ {
+ boost::optional<marker_ptr> mark = mapnik::marker_cache::instance()->find(filename, true);
+ if (mark && *mark)
{
- boost::optional<marker_ptr> mark = mapnik::marker_cache::instance()->find(filename, true);
- if (mark && *mark)
+ if (!(*mark)->is_vector())
{
- if (!(*mark)->is_vector())
- {
- MAPNIK_LOG_DEBUG(cairo_renderer) << "cairo_renderer_base: markers_symbolizer does not yet support non-SVG markers";
+ MAPNIK_LOG_DEBUG(cairo_renderer) << "cairo_renderer_base: markers_symbolizer does not yet support non-SVG markers";
- return;
- }
- boost::optional<path_ptr> marker = (*mark)->get_vector_data();
- box2d<double> const& bbox = (*marker)->bounding_box();
- double x1 = bbox.minx();
- double y1 = bbox.miny();
- double x2 = bbox.maxx();
- double y2 = bbox.maxy();
- double w = (*mark)->width();
- double h = (*mark)->height();
-
- agg::trans_affine recenter = agg::trans_affine_translation(-0.5*(x1+x2),-0.5*(y1+y2));
- tr.transform(&x1,&y1);
- tr.transform(&x2,&y2);
- box2d<double> extent(x1,y1,x2,y2);
- using namespace mapnik::svg;
-
- for (unsigned i=0; i<feature.num_geometries(); ++i)
- {
- geometry_type & geom = feature.get_geometry(i);
- // TODO - merge this code with point_symbolizer rendering
- if (placement_method == MARKER_POINT_PLACEMENT || geom.num_points() <= 1)
- {
- double x;
- double y;
- double z=0;
- geom.label_interior_position(&x, &y);
- prj_trans.backward(x,y,z);
- t_.forward(&x,&y);
- extent.re_center(x,y);
-
- if (sym.get_allow_overlap() ||
- detector_.has_placement(extent))
- {
- render_marker(pixel_position(x - 0.5 * w, y - 0.5 * h) ,**mark, tr, sym.get_opacity());
-
- // TODO - impl this for markers?
- //if (!sym.get_ignore_placement())
- // detector_.insert(label_ext);
- metawriter_with_properties writer = sym.get_metawriter();
- if (writer.first) writer.first->add_box(extent, feature, t_, writer.second);
- }
- }
- else
- {
- clipped_geometry_type clipped(geom);
- clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy());
- path_type path(t_,clipped,prj_trans);
- markers_placement<path_type, label_collision_detector4> placement(path, extent, recenter * tr, detector_,
- sym.get_spacing() * scale_factor_,
- sym.get_max_error(),
- sym.get_allow_overlap());
- double x, y, angle;
- while (placement.get_point(x, y, angle))
- {
- agg::trans_affine matrix = recenter * tr * agg::trans_affine_rotation(angle) * agg::trans_affine_translation(x, y);
- render_marker(pixel_position(x - 0.5 * w, y - 0.5 * h), **mark, matrix, sym.get_opacity(),false);
-
- if (writer.first)
- {
- //writer.first->add_box(label_ext, feature, t_, writer.second);
- MAPNIK_LOG_WARN(cairo_renderer) << "metawriter not yet supported for LINE placement";
- }
- }
- }
- context.fill();
- }
+ return;
}
- }
- else
- {
- color const& fill_ = sym.get_fill();
- stroke const& stroke_ = sym.get_stroke();
- color const& col = stroke_.get_color();
- double strk_width = stroke_.get_width();
- double w = (boost::apply_visitor(evaluate<Feature,value_type>(feature), *(sym.get_width()))).to_double() * scale_factor_;
- double h = (boost::apply_visitor(evaluate<Feature,value_type>(feature), *(sym.get_height()))).to_double() * scale_factor_;
- double rx = w/2.0;
- double ry = h/2.0;
-
- arrow arrow_;
- box2d<double> extent;
-
- double dx = w + (2*strk_width);
- double dy = h + (2*strk_width);
-
- if (marker_type == MARKER_ARROW)
- {
- extent = arrow_.extent();
- double x1 = extent.minx();
- double y1 = extent.miny();
- double x2 = extent.maxx();
- double y2 = extent.maxy();
- tr.transform(&x1,&y1);
- tr.transform(&x2,&y2);
- extent.init(x1,y1,x2,y2);
- }
- else
- {
- double x1 = -1 *(dx);
- double y1 = -1 *(dy);
- double x2 = dx;
- double y2 = dy;
- tr.transform(&x1,&y1);
- tr.transform(&x2,&y2);
- extent.init(x1,y1,x2,y2);
- }
-
- double x;
- double y;
- double z=0;
-
- agg::path_storage marker;
+ boost::optional<path_ptr> marker = (*mark)->get_vector_data();
+ box2d<double> const& bbox = (*marker)->bounding_box();
+ double x1 = bbox.minx();
+ double y1 = bbox.miny();
+ double x2 = bbox.maxx();
+ double y2 = bbox.maxy();
+ double w = (*mark)->width();
+ double h = (*mark)->height();
+
+ agg::trans_affine recenter = agg::trans_affine_translation(-0.5*(x1+x2),-0.5*(y1+y2));
+ tr.transform(&x1,&y1);
+ tr.transform(&x2,&y2);
+ box2d<double> extent(x1,y1,x2,y2);
+ using namespace mapnik::svg;
for (unsigned i=0; i<feature.num_geometries(); ++i)
{
geometry_type & geom = feature.get_geometry(i);
+ // TODO - merge this code with point_symbolizer rendering
if (placement_method == MARKER_POINT_PLACEMENT || geom.num_points() <= 1)
{
- geom.label_position(&x,&y);
+ double x;
+ double y;
+ double z=0;
+ geom.label_interior_position(&x, &y);
prj_trans.backward(x,y,z);
t_.forward(&x,&y);
- int px = int(floor(x - 0.5 * dx));
- int py = int(floor(y - 0.5 * dy));
- box2d<double> label_ext (px, py, px + dx +1, py + dy +1);
+ extent.re_center(x,y);
+
if (sym.get_allow_overlap() ||
- detector_.has_placement(label_ext))
+ detector_.has_placement(extent))
{
- agg::ellipse c(x, y, rx, ry);
- marker.concat_path(c);
- context.set_color(fill_,sym.get_opacity());
- context.add_agg_path(marker);
- context.fill();
-
- if (strk_width)
- {
- //context.restore();
- context.set_color(col,stroke_.get_opacity());
- context.set_line_width(stroke_.get_width());
- if (stroke_.has_dash())
- {
- context.set_dash(stroke_.get_dash_array());
- }
- context.add_agg_path(marker);
- context.stroke();
- }
- if (!sym.get_ignore_placement())
- detector_.insert(label_ext);
- if (writer.first) writer.first->add_box(label_ext, feature, t_, writer.second);
+ render_marker(pixel_position(x - 0.5 * w, y - 0.5 * h) ,**mark, tr, sym.get_opacity());
+
+ // TODO - impl this for markers?
+ //if (!sym.get_ignore_placement())
+ // detector_.insert(label_ext);
}
}
else
{
- if (marker_type == MARKER_ARROW)
- marker.concat_path(arrow_);
-
clipped_geometry_type clipped(geom);
clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy());
path_type path(t_,clipped,prj_trans);
- markers_placement<path_type, label_collision_detector4> placement(path, extent, agg::trans_affine(), detector_,
+ markers_placement<path_type, label_collision_detector4> placement(path, extent, recenter * tr, detector_,
sym.get_spacing() * scale_factor_,
sym.get_max_error(),
sym.get_allow_overlap());
- double x_t, y_t, angle;
- while (placement.get_point(x_t, y_t, angle))
+ double x, y, angle;
+ while (placement.get_point(x, y, angle))
{
- agg::trans_affine matrix;
-
- if (marker_type == MARKER_ELLIPSE)
- {
- agg::ellipse c(x_t, y_t, rx, ry);
- marker.concat_path(c);
- agg::trans_affine matrix;
- matrix *= agg::trans_affine_translation(-x_t,-y_t);
- matrix *= agg::trans_affine_rotation(angle);
- matrix *= agg::trans_affine_translation(x_t,y_t);
- marker.transform(matrix);
- }
- else
- {
- matrix = tr * agg::trans_affine_rotation(angle) * agg::trans_affine_translation(x_t, y_t);
- }
-
- // TODO
- if (writer.first)
- {
- //writer.first->add_box(label_ext, feature, t_, writer.second);
- MAPNIK_LOG_WARN(cairo_renderer) << "metawriter not yet supported for LINE placement";
- }
-
- agg::conv_transform<agg::path_storage, agg::trans_affine> trans(marker, matrix);
- context.set_color(fill_,sym.get_opacity());
- context.add_agg_path(trans);
- context.fill();
-
- if (strk_width)
- {
- context.set_color(col,stroke_.get_opacity());
- context.set_line_width(stroke_.get_width());
- if (stroke_.has_dash())
- {
- context.set_dash(stroke_.get_dash_array());
- }
- context.add_agg_path(trans);
- context.stroke();
- }
+ agg::trans_affine matrix = recenter * tr * agg::trans_affine_rotation(angle) * agg::trans_affine_translation(x, y);
+ render_marker(pixel_position(x - 0.5 * w, y - 0.5 * h), **mark, matrix, sym.get_opacity(),false);
}
}
+ context.fill();
}
}
}
+}
- void cairo_renderer_base::process(text_symbolizer const& sym,
- mapnik::feature_impl & feature,
- proj_transform const& prj_trans)
- {
- text_symbolizer_helper<face_manager<freetype_engine>, label_collision_detector4> helper(sym, feature, prj_trans, detector_.extent().width(), detector_.extent().height(), 1.0 /*scale_factor*/, t_, font_manager_, detector_, query_extent_);
+void cairo_renderer_base::process(text_symbolizer const& sym,
+ mapnik::feature_impl & feature,
+ proj_transform const& prj_trans)
+{
+ text_symbolizer_helper<face_manager<freetype_engine>, label_collision_detector4> helper(sym, feature, prj_trans, detector_.extent().width(), detector_.extent().height(), 1.0 /*scale_factor*/, t_, font_manager_, detector_, query_extent_);
- cairo_context context(context_);
- context.set_operator(sym.comp_op());
+ cairo_context context(context_);
+ context.set_operator(sym.comp_op());
- while (helper.next()) {
- placements_type &placements = helper.placements();
- for (unsigned int ii = 0; ii < placements.size(); ++ii)
- {
- context.add_text(placements[ii], face_manager_, font_manager_);
- }
+ while (helper.next()) {
+ placements_type &placements = helper.placements();
+ for (unsigned int ii = 0; ii < placements.size(); ++ii)
+ {
+ context.add_text(placements[ii], face_manager_, font_manager_);
}
}
+}
- template class cairo_renderer<Cairo::Surface>;
- template class cairo_renderer<Cairo::Context>;
+template class cairo_renderer<Cairo::Surface>;
+template class cairo_renderer<Cairo::Context>;
}
#endif
View
4 src/formatting/expression.cpp
@@ -74,8 +74,8 @@ node_ptr expression_format::from_xml(xml_node const& xml)
expression_ptr expression_format::get_expression(xml_node const& xml, std::string name)
{
- boost::optional<std::string> tmp = xml.get_opt_attr<std::string>(name);
- if (tmp) return parse_expression(*tmp);
+ boost::optional<expression_ptr> tmp = xml.get_opt_attr<expression_ptr>(name);
+ if (tmp) return *tmp;
return expression_ptr();
}
View
5 src/formatting/text.cpp
@@ -42,12 +42,9 @@ void text_node::to_xml(ptree &xml) const
new_node.put_value(to_expression_string(*text_));
}
-
node_ptr text_node::from_xml(xml_node const& xml)
{
- std::string data = xml.text();
- if (data.empty()) return node_ptr(); //No text
- return boost::make_shared<text_node>(parse_expression(data, "utf8"));
+ return boost::make_shared<text_node>(xml.get_value<expression_ptr>());
}
void text_node::apply(char_properties const& p, Feature const& feature, processed_text &output) const
View
1 src/grid/process_line_pattern_symbolizer.cpp
@@ -89,4 +89,3 @@ template void grid_renderer<grid>::process(line_pattern_symbolizer const&,
proj_transform const&);
}
-
View
4 src/grid/process_line_symbolizer.cpp
@@ -99,7 +99,7 @@ void grid_renderer<T>::process(line_symbolizer const& sym,
else
stroke.generator().line_cap(agg::round_cap);
- stroke.generator().miter_limit(4.0);
+ stroke.generator().miter_limit(stroke_.get_miterlimit());
stroke.generator().width(stroke_.get_width() * scale_factor_);
ras_ptr->add_path(stroke);
@@ -126,7 +126,7 @@ void grid_renderer<T>::process(line_symbolizer const& sym,
else
stroke.generator().line_cap(agg::round_cap);
- stroke.generator().miter_limit(4.0);
+ stroke.generator().miter_limit(stroke_.get_miterlimit());
stroke.generator().width(stroke_.get_width() * scale_factor_);
ras_ptr->add_path(stroke);
}
View
138 src/grid/process_markers_symbolizer.cpp
@@ -74,7 +74,6 @@ void grid_renderer<T>::process(markers_symbolizer const& sym,
tr = agg::trans_affine_scaling(scale_factor_*(1.0/res)) * tr;
std::string filename = path_processor_type::evaluate(*sym.get_filename(), feature);
marker_placement_e placement_method = sym.get_marker_placement();
- marker_type_e marker_type = sym.get_marker_type();
if (!filename.empty())
{
@@ -149,143 +148,6 @@ void grid_renderer<T>::process(markers_symbolizer const& sym,
pixmap_.add_feature(feature);
}
}
- else
- {
-
- double w = (boost::apply_visitor(evaluate<Feature,value_type>(feature), *(sym.get_width()))).to_double() * scale_factor_;
- double h = (boost::apply_visitor(evaluate<Feature,value_type>(feature), *(sym.get_height()))).to_double() * scale_factor_;
- // clamp to at least 4 px otherwise interactive pixels can be too small
- if (res == 1) {
- w = std::max(w,4.0);
- h = std::max(h,4.0);
- } else {
- double min = static_cast<double>(4.0/res);
- w = std::max(w/res,min);
- h = std::max(h/res,min);
- }
-
- double rx = w/2.0;
- double ry = h/2.0;
-
- arrow arrow_;
- box2d<double> extent;
-
- stroke const& stroke_ = sym.get_stroke();
- double strk_width = stroke_.get_width();
-
- double dx = w + (2*strk_width);
- double dy = h + (2*strk_width);
-
- if (marker_type == MARKER_ARROW)
- {
- extent = arrow_.extent();
- double x1 = extent.minx();
- double y1 = extent.miny();
- double x2 = extent.maxx();
- double y2 = extent.maxy();
- tr.transform(&x1,&y1);
- tr.transform(&x2,&y2);
- extent.init(x1,y1,x2,y2);
- }
- else
- {
- double x1 = -1 *(dx);
- double y1 = -1 *(dy);
- double x2 = dx;
- double y2 = dy;
- tr.transform(&x1,&y1);
- tr.transform(&x2,&y2);
- extent.init(x1,y1,x2,y2);
- }
-
- double x;
- double y;
- double z=0;
-
- for (unsigned i=0; i<feature.num_geometries(); ++i)
- {
- geometry_type & geom = feature.get_geometry(i);
- if (placement_method == MARKER_POINT_PLACEMENT || geom.num_points() <= 1)
- {
- geom.label_position(&x,&y);
- prj_trans.backward(x,y,z);
- t_.forward(&x,&y);
- int px = int(floor(x - 0.5 * dx));
- int py = int(floor(y - 0.5 * dy));
- box2d<double> label_ext (px, py, px + dx +1, py + dy +1);
-
- if (sym.get_allow_overlap() ||
- detector_.has_placement(label_ext))
- {
- agg::ellipse c(x, y, rx, ry);
- agg::path_storage marker;
- marker.concat_path(c);
- ras_ptr->add_path(marker);
-
- // outline
- if (strk_width)
- {
- agg::conv_stroke<agg::path_storage> outline(marker);
- outline.generator().width(strk_width * scale_factor_);
- ras_ptr->add_path(outline);
- }
-
- detector_.insert(label_ext);
- }
- }
- else
- {
-
- agg::path_storage marker;
- if (marker_type == MARKER_ARROW)
- marker.concat_path(arrow_);
-
- path_type path(t_,geom,prj_trans);
- markers_placement<path_type, label_collision_detector4> placement(path, extent, agg::trans_affine() ,detector_,
- sym.get_spacing() * scale_factor_,
- sym.get_max_error(),
- sym.get_allow_overlap());
- double x_t, y_t, angle;
- while (placement.get_point(x_t, y_t, angle))
- {
- agg::trans_affine matrix;
-
- if (marker_type == MARKER_ELLIPSE)
- {
- // todo proper bbox - this is buggy
- agg::ellipse c(x_t, y_t, rx, ry);
- marker.concat_path(c);
- agg::trans_affine matrix;
- matrix *= agg::trans_affine_translation(-x_t,-y_t);
- matrix *= agg::trans_affine_rotation(angle);
- matrix *= agg::trans_affine_translation(x_t,y_t);
- marker.transform(matrix);
- }
- else
- {
- matrix = tr * agg::trans_affine_rotation(angle) * agg::trans_affine_translation(x_t, y_t);
- }
-
- agg::conv_transform<agg::path_storage, agg::trans_affine> trans(marker, matrix);
-
- // fill
- ras_ptr->add_path(trans);
-
- // outline
- if (strk_width)
- {
- agg::conv_stroke<agg::conv_transform<agg::path_storage, agg::trans_affine> > outline(trans);
- outline.generator().width(strk_width * scale_factor_);
- ras_ptr->add_path(outline);
- }
- }
- }
-
- }
- ren.color(mapnik::gray32(feature.id()));
- agg::render_scanlines(*ras_ptr, sl, ren);
- pixmap_.add_feature(feature);
- }
}
template void grid_renderer<grid>::process(markers_symbolizer const&,
View
95 src/load_map.cpp
@@ -115,7 +115,7 @@ class map_parser : boost::noncopyable {
void parse_markers_symbolizer(rule & rule, xml_node const& sym);
void parse_raster_colorizer(raster_colorizer_ptr const& rc, xml_node const& node);
- void parse_stroke(stroke & strk, xml_node const & sym);
+ bool parse_stroke(stroke & strk, xml_node const & sym);
void ensure_font_face(std::string const& face_name);
void find_unused_nodes(xml_node const& root);
@@ -441,45 +441,45 @@ void map_parser::parse_style(Map & map, xml_node const& sty)
// image filters
mapnik::image_filter_grammar<std::string::const_iterator,
std::vector<mapnik::filter::filter_type> > filter_grammar;
-
+
optional<std::string> filters = sty.get_opt_attr<std::string>("image-filters");
if (filters)
{
std::string filter_mode = *filters;
std::string::const_iterator itr = filter_mode.begin();
std::string::const_iterator end = filter_mode.end();
-
- bool result = boost::spirit::qi::phrase_parse(itr,end,
- filter_grammar,
- boost::spirit::qi::ascii::space,
+
+ bool result = boost::spirit::qi::phrase_parse(itr,end,
+ filter_grammar,
+ boost::spirit::qi::ascii::space,
style.image_filters());
if (!result || itr!=end)
{
throw config_error("failed to parse image-filters: '" + std::string(itr,end) + "'");
- }
+ }
}
-
- // direct image filters (applied directly on main image buffer
- // TODO : consider creating a separate XML node e.g
- // <ImageFilter name="myfilter" op="blur emboss"/>
- //
+
+ // direct image filters (applied directly on main image buffer
+ // TODO : consider creating a separate XML node e.g
+ // <ImageFilter name="myfilter" op="blur emboss"/>
+ //
optional<std::string> direct_filters = sty.get_opt_attr<std::string>("direct-image-filters");
if (direct_filters)
{
std::string filter_mode = *direct_filters;
std::string::const_iterator itr = filter_mode.begin();
- std::string::const_iterator end = filter_mode.end();
- bool result = boost::spirit::qi::phrase_parse(itr,end,
- filter_grammar,
- boost::spirit::qi::ascii::space,
+ std::string::const_iterator end = filter_mode.end();
+ bool result = boost::spirit::qi::phrase_parse(itr,end,
+ filter_grammar,
+ boost::spirit::qi::ascii::space,
style.direct_image_filters());
if (!result || itr!=end)
{
throw config_error("failed to parse direct-image-filters: '" + std::string(itr,end) + "'");
- }
+ }
}
-
+
// rules
xml_node::const_iterator ruleIter = sty.begin();
xml_node::const_iterator endRule = sty.end();
@@ -839,7 +839,7 @@ void map_parser::parse_symbolizer_base(symbolizer_base &sym, xml_node const &pt)
throw config_error("failed to parse comp-op: '" + *comp_op_name + "'");
}
}
-
+
optional<std::string> geometry_transform_wkt = pt.get_opt_attr<std::string>("geometry-transform");
if (geometry_transform_wkt)
{
@@ -855,14 +855,14 @@ void map_parser::parse_symbolizer_base(symbolizer_base &sym, xml_node const &pt)
}
sym.set_transform(tl);
}
-
+
optional<boolean> clip = pt.get_opt_attr<boolean>("clip");
if (clip) sym.set_clip(*clip);
-
+
// smooth value
optional<double> smooth = pt.get_opt_attr<double>("smooth");
if (smooth) sym.set_smooth(*smooth);
-
+
optional<std::string> writer = pt.get_opt_attr<std::string>("meta-writer");
if (!writer) return;
optional<std::string> output = pt.get_opt_attr<std::string>("meta-output");
@@ -878,7 +878,7 @@ void map_parser::parse_point_symbolizer(rule & rule, xml_node const & sym)
optional<boolean> allow_overlap = sym.get_opt_attr<boolean>("allow-overlap");
optional<boolean> ignore_placement = sym.get_opt_attr<boolean>("ignore-placement");
optional<float> opacity = sym.get_opt_attr<float>("opacity");
-
+
point_symbolizer symbol;
if (allow_overlap)
{
@@ -1019,7 +1019,7 @@ void map_parser::parse_markers_symbolizer(rule & rule, xml_node const& sym)
}
symbol.set_image_transform(tl);
}
-
+
optional<color> c = sym.get_opt_attr<color>("fill");
if (c) symbol.set_fill(*c);
optional<double> spacing = sym.get_opt_attr<double>("spacing");
@@ -1052,22 +1052,11 @@ void map_parser::parse_markers_symbolizer(rule & rule, xml_node const& sym)
}
stroke strk;
- parse_stroke(strk,sym);
- symbol.set_stroke(strk);
+ if (parse_stroke(strk,sym))
+ symbol.set_stroke(strk);
marker_placement_e placement = sym.get_attr<marker_placement_e>("placement", MARKER_LINE_PLACEMENT);
symbol.set_marker_placement(placement);
-
- marker_type_e dfl_marker_type = MARKER_ARROW;
-
- if (placement == MARKER_POINT_PLACEMENT)
- {
- dfl_marker_type = MARKER_ELLIPSE;
- }
-
- marker_type_e marker_type = sym.get_attr<marker_type_e>("marker-type", dfl_marker_type);
- symbol.set_marker_type(marker_type);
-
parse_symbolizer_base(symbol, sym);
rule.append(symbol);
}
@@ -1152,11 +1141,11 @@ void map_parser::parse_polygon_pattern_symbolizer(rule & rule,
// pattern alignment
pattern_alignment_e p_alignment = sym.get_attr<pattern_alignment_e>("alignment",LOCAL_ALIGNMENT);
symbol.set_alignment(p_alignment);
-
+
// opacity
optional<double> opacity