diff --git a/include/mapnik/ctrans.hpp b/include/mapnik/ctrans.hpp index 58a56a44a..32f662d32 100644 --- a/include/mapnik/ctrans.hpp +++ b/include/mapnik/ctrans.hpp @@ -60,6 +60,9 @@ private: template struct MAPNIK_DECL coord_transform2 { + typedef std::size_t size_type; + typedef typename Geometry::value_type value_type; + coord_transform2(Transform const& t, Geometry const& geom, proj_transform const& prj_trans) diff --git a/include/mapnik/geometry.hpp b/include/mapnik/geometry.hpp index 293215354..5aff4e3e9 100644 --- a/include/mapnik/geometry.hpp +++ b/include/mapnik/geometry.hpp @@ -48,7 +48,6 @@ class geometry { public: typedef T vertex_type; - typedef std::size_t size_type; typedef typename vertex_type::type value_type; typedef Container container_type; private: diff --git a/include/mapnik/svg/svg_output_grammars.hpp b/include/mapnik/svg/svg_output_grammars.hpp index bce3f1603..0cf1e300a 100644 --- a/include/mapnik/svg/svg_output_grammars.hpp +++ b/include/mapnik/svg/svg_output_grammars.hpp @@ -25,9 +25,9 @@ // mapnik #include -#include -#include #include +#include +#include #include // boost @@ -94,34 +94,36 @@ BOOST_FUSION_ADAPT_STRUCT( */ namespace boost { namespace spirit { namespace traits { + typedef mapnik::coord_transform2 path_type; + template <> - struct is_container + struct is_container : mpl::true_ {}; template <> - struct container_iterator + struct container_iterator { - typedef mapnik::geometry_iterator_type type; + typedef mapnik::svg::path_iterator_type type; }; template <> - struct begin_container + struct begin_container { - static mapnik::geometry_iterator_type - call(mapnik::geometry_type const& g) + static mapnik::svg::path_iterator_type + call(path_type const& path) { - return mapnik::geometry_iterator_type(0, g); + return mapnik::svg::path_iterator_type(0, path); } }; template <> - struct end_container + struct end_container { - static mapnik::geometry_iterator_type - call(mapnik::geometry_type const& g) + static mapnik::svg::path_iterator_type + call(path_type const& path) { - return mapnik::geometry_iterator_type(g); + return mapnik::svg::path_iterator_type(path); } }; }}} @@ -131,67 +133,17 @@ namespace mapnik { namespace svg { using namespace boost::spirit; using namespace boost::phoenix; - /*! - * @brief Structure that performs the conversion from map to user coordinates. - * It's methods and functions are meant to be used by svg_path_data_grammar as - * semantic actions to convert the value of vertex coordinates inside the grammar. - * - * It (kind of) works like a state machine, setting the value of x and y and then - * making the conversion just after y has been set. - */ - template - struct path_coordinate_transformer - { - explicit path_coordinate_transformer(PathType const& path_type) - : path_type_(path_type), - current_x_(0.0), - current_y_(0.0) - {} - - void set_current_x(double& x) - { - current_x_ = x; - } - - void set_current_y(double& y) - { - current_y_ = y; - path_type_.vertex(¤t_x_, ¤t_y_); - } - - void current_x(double& x) const - { - x = current_x_; - } - - void current_y(double& y) const - { - y = current_y_; - } - - PathType const& path_type_; - double current_x_; - double current_y_; - }; - template - struct svg_path_data_grammar : karma::grammar + struct svg_path_data_grammar : karma::grammar { - typedef path_coordinate_transformer coordinate_transformer; - typedef mapnik::geometry_iterator_type::value_type vertex_type; - typedef mapnik::geometry_type::value_type& vertex_component_type; + typedef path_iterator_type::value_type vertex_type; explicit svg_path_data_grammar(PathType const& path_type) : svg_path_data_grammar::base_type(svg_path), - path_type_(path_type), - ct_(path_type) + path_type_(path_type) { using karma::int_; using karma::double_; - using karma::_1; - using karma::_a; - using karma::eol; - using karma::omit; using repository::confix; svg_path = @@ -201,31 +153,18 @@ namespace mapnik { namespace svg { path_vertex = path_vertex_command - << omit[path_vertex_component_x] - << omit[path_vertex_component_y] - << path_vertex_transformed_x + << double_ << lit(' ') - << path_vertex_transformed_y; + << double_; path_vertex_command = &int_(1) << lit('M') | lit('L'); - - path_vertex_component_x = double_[_1 = _a][bind(&coordinate_transformer::set_current_x, &ct_, _a)][_a = _val]; - - path_vertex_component_y = double_[_1 = _a][bind(&coordinate_transformer::set_current_y, &ct_, _a)][_a = _val]; - - path_vertex_transformed_x = double_[_1 = _a][bind(&coordinate_transformer::current_x, &ct_, _a)]; - - path_vertex_transformed_y = double_[_1 = _a][bind(&coordinate_transformer::current_y, &ct_, _a)]; } - karma::rule svg_path; + karma::rule svg_path; karma::rule path_vertex; karma::rule path_vertex_command; - karma::rule > path_vertex_component_x, path_vertex_component_y; - karma::rule > path_vertex_transformed_x, path_vertex_transformed_y; PathType const& path_type_; - coordinate_transformer ct_; }; template diff --git a/include/mapnik/geometry_iterator.hpp b/include/mapnik/svg/svg_path_iterator.hpp similarity index 79% rename from include/mapnik/geometry_iterator.hpp rename to include/mapnik/svg/svg_path_iterator.hpp index f12fda8d8..9957f2e27 100644 --- a/include/mapnik/geometry_iterator.hpp +++ b/include/mapnik/svg/svg_path_iterator.hpp @@ -20,11 +20,12 @@ * *****************************************************************************/ -#ifndef GEOMETRY_ITERATOR_HPP -#define GEOMETRY_ITERATOR_HPP +#ifndef SVG_PATH_ITERATOR_HPP +#define SVG_PATH_ITERATOR_HPP // mapnik #include +#include // boost #include @@ -32,6 +33,9 @@ #include namespace mapnik { +namespace svg { + +using namespace mapnik; /* * @brief Iterator class used to iterate over geometry vertexes. @@ -47,9 +51,9 @@ namespace mapnik { * @tparam Value the type of sequence element dereferenced. * @tparam Container the sequence over which it iterates. */ -template -class geometry_iterator - : public boost::iterator_adaptor, +template +class path_iterator + : public boost::iterator_adaptor, Value*, boost::use_default, boost::forward_traversal_tag> @@ -57,6 +61,7 @@ class geometry_iterator public: typedef Value value_type; typedef Container container_type; + typedef typename Container::value_type value_component_type; /*! * @brief Constructor that initializes the reference to the current element to null. @@ -65,10 +70,10 @@ public: * * @param geometry the geometry that handles the vector of vertexes. */ - geometry_iterator(Container const& geometry) - : geometry_iterator::iterator_adaptor_(0), - geometry_(geometry), - first_value_(new Value(0,0,0,0,0)) + path_iterator(Container const& path) + : path_iterator::iterator_adaptor_(0), + path_(path), + first_value_(new Value(0,0,0)) {} /*! @@ -82,10 +87,10 @@ public: * @param p pointer to the first element of the sequence. * @param geometry the geometry that handles the vector of vertexes. */ - explicit geometry_iterator(Value* first_element, Container const& geometry) - : geometry_iterator::iterator_adaptor_(first_element), - geometry_(geometry), - first_value_(new Value(0,0,0,0,0)) + explicit path_iterator(Value* first_element, Container const& path) + : path_iterator::iterator_adaptor_(first_element), + path_(path), + first_value_(new Value(0,0,0)) { this->increment(); } @@ -97,10 +102,10 @@ public: * @sa http://www.boost.org/doc/libs/1_45_0/libs/iterator/doc/iterator_facade.html#interoperability */ template - geometry_iterator(geometry_iterator const& other, + path_iterator(path_iterator const& other, typename boost::enable_if, enabler>::type = enabler()) - : geometry_iterator::iterator_adaptor_(other.base()) {} + : path_iterator::iterator_adaptor_(other.base()) {} private: @@ -117,7 +122,7 @@ private: geometry_type::value_type y; // extract next vertex components. - unsigned cmd = geometry_.vertex(&x, &y); + unsigned cmd = path_.vertex(&x, &y); if(cmd == SEG_END) { @@ -137,13 +142,13 @@ private: // 'first_value_' is used as intermediate storage // because the compiler prohibits the assignment of the // address of a temporary object (&Value(...)). - *first_value_ = Value(cmd, x, y, x, y); + *first_value_ = Value(cmd, x, y); this->base_reference() = first_value_.get(); } else { // point the reference to the current element to the next. - *(this->base_reference()) = Value(cmd, x, y, x, y); + *(this->base_reference()) = Value(cmd, x, y); } } @@ -153,21 +158,23 @@ private: * @param other iterator to compare to current element. */ template - bool equal(geometry_iterator const& other) const + bool equal(path_iterator const& other) const { return this->base_reference() == other.base(); } - Container const& geometry_; + Container const& path_; boost::shared_ptr first_value_; }; /*! * @brief Specialization of geometry_iterator, as needed by mapnik::svg::svg_path_data_grammar. * The Value type is a boost::tuple that holds 5 elements, the command and the x and y coordinate. - * Each coordinate is stored twice to match the needs the grammar. + * Each coordinate is stored twice to match the needs of the grammar. */ -typedef geometry_iterator, geometry_type> geometry_iterator_type; -} +typedef path_iterator, + coord_transform2 > path_iterator_type; -#endif //GEOMETRY_ITERATOR_HPP +}} + +#endif //SVG_PATH_ITERATOR_HPP diff --git a/src/svg/svg_generator.cpp b/src/svg/svg_generator.cpp index 69de87f61..164ae8040 100644 --- a/src/svg/svg_generator.cpp +++ b/src/svg/svg_generator.cpp @@ -73,7 +73,7 @@ namespace mapnik { namespace svg { path_attributes_grammar attributes_grammar; path_dash_array_grammar dash_array_grammar; - karma::generate(output_iterator_, lit("\n"), path_attributes); } diff --git a/tests/cpp_tests/svg_renderer_tests/path_element_test.cpp b/tests/cpp_tests/svg_renderer_tests/path_element_test.cpp index 4e62199c9..5fe1268bd 100644 --- a/tests/cpp_tests/svg_renderer_tests/path_element_test.cpp +++ b/tests/cpp_tests/svg_renderer_tests/path_element_test.cpp @@ -172,7 +172,7 @@ void prepare_map(Map& m) lyr.add_style("provlines"); m.addLayer(lyr); } - + // Roads { parameters p;