diff --git a/CHANGELOG b/CHANGELOG index f0deb03ae..e95b743d3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -14,6 +14,8 @@ For a complete change history, see the SVN log. Mapnik Trunk ------------ +- Added support for setting global alignment of polygon pattern fills (#203) + - Added support for choosing OGR layer by index number using 'layer_by_index' parameter (r1904) - Added support for reading jpeg images (in addition to png/tiff) for image symbolizers (#518) diff --git a/bindings/python/mapnik/__init__.py b/bindings/python/mapnik/__init__.py index 6b2652cd6..903af05ee 100644 --- a/bindings/python/mapnik/__init__.py +++ b/bindings/python/mapnik/__init__.py @@ -658,9 +658,15 @@ __all__ = [ 'TextSymbolizer', 'ViewTransform', # enums - 'aspect_fix_mode', 'label_placement', - 'line_cap', 'line_join', - 'text_convert', 'vertical_alignment', + 'aspect_fix_mode', + 'label_placement', + 'line_cap', + 'line_join', + 'text_convert', + 'vertical_alignment', + 'horizontal_alignment', + 'justify_alignment', + 'pattern_alignment', # functions # datasources 'Datasource', 'CreateDatasource', diff --git a/bindings/python/mapnik_polygon_pattern_symbolizer.cpp b/bindings/python/mapnik_polygon_pattern_symbolizer.cpp index 4eabdcff8..356cabc89 100644 --- a/bindings/python/mapnik_polygon_pattern_symbolizer.cpp +++ b/bindings/python/mapnik_polygon_pattern_symbolizer.cpp @@ -24,8 +24,10 @@ #include #include #include +#include "mapnik_enumeration.hpp" #include +using namespace mapnik; using mapnik::polygon_pattern_symbolizer; using mapnik::path_expression_ptr; using mapnik::path_processor_type; @@ -39,13 +41,47 @@ struct polygon_pattern_symbolizer_pickle_suite : boost::python::pickle_suite std::string filename = path_processor_type::to_string(*p.get_filename()); return boost::python::make_tuple(filename,guess_type(filename)); } + + static boost::python::tuple + getstate(const polygon_pattern_symbolizer& p) + { + return boost::python::make_tuple(p.get_alignment()); + } + + static void + setstate (polygon_pattern_symbolizer& p, boost::python::tuple state) + { + using namespace boost::python; + if (len(state) != 1) + { + PyErr_SetObject(PyExc_ValueError, + ("expected 1-item tuple in call to __setstate__; got %s" + % state).ptr() + ); + throw_error_already_set(); + } + + p.set_alignment(extract(state[0])); + } + }; void export_polygon_pattern_symbolizer() { using namespace boost::python; + + enumeration_("pattern_alignment") + .value("LOCAL",LOCAL_ALIGNMENT) + .value("GLOBAL",GLOBAL_ALIGNMENT) + ; class_("PolygonPatternSymbolizer", init("")) - .def_pickle(polygon_pattern_symbolizer_pickle_suite()) ; + .def_pickle(polygon_pattern_symbolizer_pickle_suite()) + .add_property("pattern_alignment", + &polygon_pattern_symbolizer::get_alignment, + &polygon_pattern_symbolizer::set_alignment, + "Set/get the alignment of the pattern") + + ; } diff --git a/include/mapnik/polygon_pattern_symbolizer.hpp b/include/mapnik/polygon_pattern_symbolizer.hpp index db66f21fb..ea6cf9922 100644 --- a/include/mapnik/polygon_pattern_symbolizer.hpp +++ b/include/mapnik/polygon_pattern_symbolizer.hpp @@ -26,15 +26,32 @@ // mapnik #include +#include +#include namespace mapnik { + +enum pattern_alignment_enum { + LOCAL_ALIGNMENT, + GLOBAL_ALIGNMENT, + pattern_alignment_enum_MAX +}; + +DEFINE_ENUM( pattern_alignment_e, pattern_alignment_enum ); + struct MAPNIK_DECL polygon_pattern_symbolizer : public symbolizer_with_image { polygon_pattern_symbolizer(path_expression_ptr file); polygon_pattern_symbolizer(polygon_pattern_symbolizer const& rhs); + pattern_alignment_e get_alignment() const; + void set_alignment(pattern_alignment_e align); + +private: + pattern_alignment_e alignment_; + }; } diff --git a/src/agg/process_polygon_pattern_symbolizer.cpp b/src/agg/process_polygon_pattern_symbolizer.cpp index 93af1aa61..7c3f6842c 100644 --- a/src/agg/process_polygon_pattern_symbolizer.cpp +++ b/src/agg/process_polygon_pattern_symbolizer.cpp @@ -85,15 +85,24 @@ void agg_renderer::process(polygon_pattern_symbolizer const& sym, agg::row_accessor, agg::pixel32_type> pixf_pattern(pattern_rbuf); img_source_type img_src(pixf_pattern); - double x0=0,y0=0; unsigned num_geometries = feature.num_geometries(); - if (num_geometries>0) + + pattern_alignment_e align = sym.get_alignment(); + unsigned offset_x=0; + unsigned offset_y=0; + + if (align == LOCAL_ALIGNMENT) { - path_type path(t_,feature.get_geometry(0),prj_trans); - path.vertex(&x0,&y0); + double x0=0,y0=0; + if (num_geometries>0) + { + path_type path(t_,feature.get_geometry(0),prj_trans); + path.vertex(&x0,&y0); + } + offset_x = unsigned(width_-x0); + offset_y = unsigned(height_-y0); } - unsigned offset_x = unsigned(width_-x0); - unsigned offset_y = unsigned(height_-y0); + span_gen_type sg(img_src, offset_x, offset_y); renderer_type rp(renb,sa, sg); for (unsigned i=0;i(sym, "alignment",LOCAL_ALIGNMENT); + symbol.set_alignment(p_alignment); + rule.append(symbol); } catch (image_reader_exception const & ex ) diff --git a/src/polygon_pattern_symbolizer.cpp b/src/polygon_pattern_symbolizer.cpp index 4af1c14fe..9fa044406 100644 --- a/src/polygon_pattern_symbolizer.cpp +++ b/src/polygon_pattern_symbolizer.cpp @@ -26,14 +26,32 @@ namespace mapnik { + +static const char * pattern_alignment_strings[] = { + "local", // feature + "global", // map + "" +}; +IMPLEMENT_ENUM( pattern_alignment_e, pattern_alignment_strings ); + polygon_pattern_symbolizer::polygon_pattern_symbolizer(path_expression_ptr file) - : symbolizer_with_image(file) -{ -} + : symbolizer_with_image(file), + alignment_(LOCAL_ALIGNMENT) {} polygon_pattern_symbolizer::polygon_pattern_symbolizer(polygon_pattern_symbolizer const& rhs) - : symbolizer_with_image(rhs) {} + : symbolizer_with_image(rhs), + alignment_(rhs.alignment_) {} + +pattern_alignment_e polygon_pattern_symbolizer::get_alignment() const +{ + return alignment_; +} + +void polygon_pattern_symbolizer::set_alignment(pattern_alignment_e align) +{ + alignment_ = align; +} } diff --git a/src/save_map.cpp b/src/save_map.cpp index 2d6226d7e..250c23a97 100644 --- a/src/save_map.cpp +++ b/src/save_map.cpp @@ -172,6 +172,12 @@ public: ptree & sym_node = rule_.push_back( ptree::value_type("PolygonPatternSymbolizer", ptree()))->second; + polygon_pattern_symbolizer dfl(parse_path("")); + + if ( sym.get_alignment() != dfl.get_alignment() || explicit_defaults_ ) + { + set_attr( sym_node, "alignment", sym.get_alignment() ); + } add_image_attributes( sym_node, sym ); } diff --git a/tests/data/good_maps/polygon_pattern_symbolizer.xml b/tests/data/good_maps/polygon_pattern_symbolizer.xml new file mode 100644 index 000000000..5c04a8ca4 --- /dev/null +++ b/tests/data/good_maps/polygon_pattern_symbolizer.xml @@ -0,0 +1,39 @@ + + + + ../images/ + + + + + 1 + + shape + ../../data/shp/ + poly.shp + + + + \ No newline at end of file