diff --git a/doc/src/examples/algorithms/transform_with_strategy.cpp b/doc/src/examples/algorithms/transform_with_strategy.cpp index df44d6336..d55e5e2d1 100644 --- a/doc/src/examples/algorithms/transform_with_strategy.cpp +++ b/doc/src/examples/algorithms/transform_with_strategy.cpp @@ -25,17 +25,17 @@ int main() // Translate over (1.5, 1.5) point_type p2; - trans::translate_transformer translate(1.5, 1.5); + trans::translate_transformer translate(1.5, 1.5); boost::geometry::transform(p1, p2, translate); // Scale with factor 3.0 point_type p3; - trans::scale_transformer scale(3.0); + trans::scale_transformer scale(3.0); boost::geometry::transform(p1, p3, scale); // Rotate with respect to the origin (0,0) over 90 degrees (clockwise) point_type p4; - trans::rotate_transformer rotate(90.0); + trans::rotate_transformer rotate(90.0); boost::geometry::transform(p1, p4, rotate); std::cout diff --git a/example/06_a_transformation_example.cpp b/example/06_a_transformation_example.cpp index 367d5e16f..01a560173 100644 --- a/example/06_a_transformation_example.cpp +++ b/example/06_a_transformation_example.cpp @@ -29,7 +29,7 @@ int main() point_2d p2; // Example: translate a point over (5,5) - strategy::transform::translate_transformer translate(5, 5); + strategy::transform::translate_transformer translate(5, 5); transform(p, p2, translate); std::cout << "transformed point " << boost::geometry::dsv(p2) << std::endl; diff --git a/example/06_b_transformation_example.cpp b/example/06_b_transformation_example.cpp index 5dd972548..db125ff53 100644 --- a/example/06_b_transformation_example.cpp +++ b/example/06_b_transformation_example.cpp @@ -127,25 +127,25 @@ int main() svg.put(g1, "g1"); // G1 - Translate -> G2 - translate_transformer translate(0, 250); + translate_transformer translate(0, 250); model::polygon g2; transform(g1, g2, translate); std::clog << "translated:\t" << boost::geometry::dsv(g2) << std::endl; svg.put(g2, "g2=g1.translate(0,250)"); // G2 - Scale -> G3 - scale_transformer scale(0.5, 0.5); + scale_transformer scale(0.5, 0.5); model::polygon g3; transform(g2, g3, scale); std::clog << "scaled:\t" << boost::geometry::dsv(g3) << std::endl; svg.put(g3, "g3=g2.scale(0.5,0.5)"); // G3 - Combine rotate and translate -> G4 - rotate_transformer rotate(45); + rotate_transformer rotate(45); // Compose matrix for the two transformation // Create transformer attached to the transformation matrix - ublas_transformer + ublas_transformer combined(boost::numeric::ublas::prod(rotate.matrix(), translate.matrix())); //combined(rotate.matrix()); diff --git a/example/c11_custom_cs_transform_example.cpp b/example/c11_custom_cs_transform_example.cpp index 370d59c1d..896ee069a 100644 --- a/example/c11_custom_cs_transform_example.cpp +++ b/example/c11_custom_cs_transform_example.cpp @@ -32,9 +32,9 @@ template<> struct cs_tag { typedef cartesian_tag type; }; // 3: sample implementation of a shift // to convert coordinate system "cart" to "cart_shirted5" -template struct shift { + template inline bool apply(P1 const& p1, P2& p2) const { namespace bg = boost::geometry; @@ -52,7 +52,7 @@ namespace boost { namespace geometry { namespace strategy { namespace transform template struct default_strategy { - typedef shift type; + typedef shift type; }; }}}}} // namespaces diff --git a/include/boost/geometry/io/svg/svg_mapper.hpp b/include/boost/geometry/io/svg/svg_mapper.hpp index 1252cc806..fbe0a37da 100644 --- a/include/boost/geometry/io/svg/svg_mapper.hpp +++ b/include/boost/geometry/io/svg/svg_mapper.hpp @@ -226,10 +226,17 @@ inline void svg_map(std::ostream& stream, template class svg_mapper : boost::noncopyable { + typedef typename geometry::select_most_precise + < + typename coordinate_type::type, + double + >::type calculation_type; + typedef strategy::transform::map_transformer < - Point, - detail::svg::svg_point_type, + calculation_type, + geometry::dimension::type::value, + geometry::dimension::type::value, true, SameScale > transformer_type; @@ -247,6 +254,7 @@ class svg_mapper : boost::noncopyable m_matrix.reset(new transformer_type(m_bounding_box, m_width, m_height)); + m_stream << "" << std::endl << "" + << "xmlns=\"http://www.w3.org/2000/svg\"" + << std::endl + << "xmlns:xlink=\"http://www.w3.org/1999/xlink\"" + << ">" << std::endl; } } @@ -319,18 +330,6 @@ public : void map(Geometry const& geometry, std::string const& style, int size = -1) { - BOOST_MPL_ASSERT_MSG - ( - ( boost::is_same - < - Point, - typename point_type::type - >::value ) - , POINT_TYPES_ARE_NOT_SAME_FOR_MAPPER_AND_MAP - , (types::type>) - ); - - init_matrix(); svg_map(m_stream, style, size, geometry, *m_matrix); } diff --git a/include/boost/geometry/strategies/transform/inverse_transformer.hpp b/include/boost/geometry/strategies/transform/inverse_transformer.hpp index 845a71ded..10ad35126 100644 --- a/include/boost/geometry/strategies/transform/inverse_transformer.hpp +++ b/include/boost/geometry/strategies/transform/inverse_transformer.hpp @@ -33,20 +33,21 @@ namespace strategy { namespace transform /*! \brief Transformation strategy to do an inverse ransformation in Cartesian system \ingroup strategies -\tparam P1 first point type -\tparam P2 second point type */ -template +template +< + typename CalculationType, + std::size_t Dimension1, + std::size_t Dimension2 +> class inverse_transformer - : public ublas_transformer::type::value, dimension::type::value> + : public ublas_transformer { - typedef typename select_coordinate_type::type T; - public : template inline inverse_transformer(Transformer const& input) { - typedef boost::numeric::ublas::matrix matrix_type; + typedef boost::numeric::ublas::matrix matrix_type; // create a working copy of the input matrix_type copy(input.matrix()); @@ -60,7 +61,7 @@ public : if( res == 0 ) { // create identity matrix - this->m_matrix.assign(boost::numeric::ublas::identity_matrix(copy.size1())); + this->m_matrix.assign(boost::numeric::ublas::identity_matrix(copy.size1())); // backsubstitute to get the inverse boost::numeric::ublas::lu_substitute(copy, pm, this->m_matrix); diff --git a/include/boost/geometry/strategies/transform/map_transformer.hpp b/include/boost/geometry/strategies/transform/map_transformer.hpp index 2755d5353..7b15da275 100644 --- a/include/boost/geometry/strategies/transform/map_transformer.hpp +++ b/include/boost/geometry/strategies/transform/map_transformer.hpp @@ -34,23 +34,21 @@ namespace strategy { namespace transform /*! \brief Transformation strategy to do map from one to another Cartesian system \ingroup strategies -\tparam P1 first point type -\tparam P2 second point type \tparam Mirror if true map is mirrored upside-down (in most cases pixels are from top to bottom, while map is from bottom to top) */ template < - typename P1, typename P2, - bool Mirror = false, bool SameScale = true, - std::size_t Dimension1 = dimension::type::value, - std::size_t Dimension2 = dimension::type::value + typename CalculationType, + std::size_t Dimension1, + std::size_t Dimension2, + bool Mirror = false, + bool SameScale = true > class map_transformer - : public ublas_transformer + : public ublas_transformer { - typedef typename select_coordinate_type::type T; - typedef boost::numeric::ublas::matrix M; + typedef boost::numeric::ublas::matrix M; public : template diff --git a/include/boost/geometry/strategies/transform/matrix_transformers.hpp b/include/boost/geometry/strategies/transform/matrix_transformers.hpp index b37a3712e..fc7cd33fc 100644 --- a/include/boost/geometry/strategies/transform/matrix_transformers.hpp +++ b/include/boost/geometry/strategies/transform/matrix_transformers.hpp @@ -46,14 +46,12 @@ namespace strategy { namespace transform \see http://en.wikipedia.org/wiki/Affine_transformation and http://www.devmaster.net/wiki/Transformation_matrices \ingroup strategies -\tparam P1 first point type (source) -\tparam P2 second point type (target) -\tparam Dimension1 number of dimensions to transform from first point -\tparam Dimension1 number of dimensions to transform to second point +\tparam Dimension1 number of dimensions to transform from +\tparam Dimension2 number of dimensions to transform to */ template < - typename P1, typename P2, + typename CalculationType, std::size_t Dimension1, std::size_t Dimension2 > @@ -62,13 +60,12 @@ class ublas_transformer }; -template -class ublas_transformer +template +class ublas_transformer { protected : - typedef typename select_coordinate_type::type coordinate_type; - typedef coordinate_type ct; // Abbreviation - typedef boost::numeric::ublas::matrix matrix_type; + typedef CalculationType ct; + typedef boost::numeric::ublas::matrix matrix_type; matrix_type m_matrix; public : @@ -91,17 +88,17 @@ public : inline ublas_transformer() : m_matrix(3, 3) {} + template inline bool apply(P1 const& p1, P2& p2) const { assert_dimension_greater_equal(); assert_dimension_greater_equal(); - coordinate_type const& c1 = get<0>(p1); - coordinate_type const& c2 = get<1>(p1); + ct const& c1 = get<0>(p1); + ct const& c2 = get<1>(p1); - - coordinate_type p2x = c1 * m_matrix(0,0) + c2 * m_matrix(0,1) + m_matrix(0,2); - coordinate_type p2y = c1 * m_matrix(1,0) + c2 * m_matrix(1,1) + m_matrix(1,2); + ct p2x = c1 * m_matrix(0,0) + c2 * m_matrix(0,1) + m_matrix(0,2); + ct p2y = c1 * m_matrix(1,0) + c2 * m_matrix(1,1) + m_matrix(1,2); typedef typename geometry::coordinate_type::type ct2; set<0>(p2, boost::numeric_cast(p2x)); @@ -115,36 +112,34 @@ public : // It IS possible to go from 3 to 2 coordinates -template -class ublas_transformer : public ublas_transformer +template +class ublas_transformer : public ublas_transformer { - typedef typename select_coordinate_type::type coordinate_type; - typedef coordinate_type ct; // Abbreviation + typedef CalculationType ct; public : inline ublas_transformer( ct const& m_0_0, ct const& m_0_1, ct const& m_0_2, ct const& m_1_0, ct const& m_1_1, ct const& m_1_2, ct const& m_2_0, ct const& m_2_1, ct const& m_2_2) - : ublas_transformer( + : ublas_transformer( m_0_0, m_0_1, m_0_2, m_1_0, m_1_1, m_1_2, m_2_0, m_2_1, m_2_2) {} inline ublas_transformer() - : ublas_transformer() + : ublas_transformer() {} }; -template -class ublas_transformer +template +class ublas_transformer { protected : - typedef typename select_coordinate_type::type coordinate_type; - typedef coordinate_type ct; // Abbreviation - typedef boost::numeric::ublas::matrix matrix_type; + typedef CalculationType ct; + typedef boost::numeric::ublas::matrix matrix_type; matrix_type m_matrix; public : @@ -164,11 +159,12 @@ public : inline ublas_transformer() : m_matrix(4, 4) {} + template inline bool apply(P1 const& p1, P2& p2) const { - coordinate_type const& c1 = get<0>(p1); - coordinate_type const& c2 = get<1>(p1); - coordinate_type const& c3 = get<2>(p1); + ct const& c1 = get<0>(p1); + ct const& c2 = get<1>(p1); + ct const& c3 = get<2>(p1); typedef typename geometry::coordinate_type::type ct2; @@ -191,34 +187,30 @@ public : \details Translate moves a geometry a fixed distance in 2 or 3 dimensions. \see http://en.wikipedia.org/wiki/Translation_%28geometry%29 \ingroup strategies -\tparam P1 first point type -\tparam P2 second point type -\tparam Dimension1 number of dimensions to transform from first point -\tparam Dimension1 number of dimensions to transform to second point +\tparam Dimension1 number of dimensions to transform from +\tparam Dimension2 number of dimensions to transform to */ template < - typename P1, typename P2, - std::size_t Dimension1 = geometry::dimension::type::value, - std::size_t Dimension2 = geometry::dimension::type::value + typename CalculationType, + std::size_t Dimension1, + std::size_t Dimension2 > class translate_transformer { }; -template -class translate_transformer : public ublas_transformer +template +class translate_transformer : public ublas_transformer { - typedef typename select_coordinate_type::type coordinate_type; - public : // To have translate transformers compatible for 2/3 dimensions, the // constructor takes an optional third argument doing nothing. - inline translate_transformer(coordinate_type const& translate_x, - coordinate_type const& translate_y, - coordinate_type const& = 0) - : ublas_transformer( + inline translate_transformer(CalculationType const& translate_x, + CalculationType const& translate_y, + CalculationType const& = 0) + : ublas_transformer( 1, 0, translate_x, 0, 1, translate_y, 0, 0, 1) @@ -226,16 +218,14 @@ public : }; -template -class translate_transformer : public ublas_transformer +template +class translate_transformer : public ublas_transformer { - typedef typename select_coordinate_type::type coordinate_type; - public : - inline translate_transformer(coordinate_type const& translate_x, - coordinate_type const& translate_y, - coordinate_type const& translate_z) - : ublas_transformer( + inline translate_transformer(CalculationType const& translate_x, + CalculationType const& translate_y, + CalculationType const& translate_z) + : ublas_transformer( 1, 0, 0, translate_x, 0, 1, 0, translate_y, 0, 0, 1, translate_z, @@ -250,40 +240,37 @@ public : \details Scale scales a geometry up or down in all its dimensions. \see http://en.wikipedia.org/wiki/Scaling_%28geometry%29 \ingroup strategies -\tparam P1 first point type -\tparam P2 second point type -\tparam Dimension1 number of dimensions to transform from first point -\tparam Dimension1 number of dimensions to transform to second point +\tparam Dimension1 number of dimensions to transform from +\tparam Dimension2 number of dimensions to transform to */ template < - typename P1, typename P2 = P1, - std::size_t Dimension1 = geometry::dimension::type::value, - std::size_t Dimension2 = geometry::dimension::type::value + typename CalculationType, + std::size_t Dimension1, + std::size_t Dimension2 > class scale_transformer { }; -template -class scale_transformer : public ublas_transformer +template +class scale_transformer : public ublas_transformer { - typedef typename select_coordinate_type::type coordinate_type; public : - inline scale_transformer(coordinate_type const& scale_x, - coordinate_type const& scale_y, - coordinate_type const& = 0) - : ublas_transformer( + inline scale_transformer(CalculationType const& scale_x, + CalculationType const& scale_y, + CalculationType const& = 0) + : ublas_transformer( scale_x, 0, 0, 0, scale_y, 0, 0, 0, 1) {} - inline scale_transformer(coordinate_type const& scale) - : ublas_transformer( + inline scale_transformer(CalculationType const& scale) + : ublas_transformer( scale, 0, 0, 0, scale, 0, 0, 0, 1) @@ -291,16 +278,14 @@ public : }; -template -class scale_transformer : public ublas_transformer +template +class scale_transformer : public ublas_transformer { - typedef typename select_coordinate_type::type coordinate_type; - public : - inline scale_transformer(coordinate_type const& scale_x, - coordinate_type const& scale_y, - coordinate_type const& scale_z) - : ublas_transformer( + inline scale_transformer(CalculationType const& scale_x, + CalculationType const& scale_y, + CalculationType const& scale_z) + : ublas_transformer( scale_x, 0, 0, 0, 0, scale_y, 0, 0, 0, 0, scale_z, 0, @@ -308,8 +293,8 @@ public : {} - inline scale_transformer(coordinate_type const& scale) - : ublas_transformer( + inline scale_transformer(CalculationType const& scale) + : ublas_transformer( scale, 0, 0, 0, 0, scale, 0, 0, 0, 0, scale, 0, @@ -352,23 +337,16 @@ struct as_radian template < - typename P1, typename P2, - std::size_t Dimension1 = geometry::dimension::type::value, - std::size_t Dimension2 = geometry::dimension::type::value + typename CalculationType, + std::size_t Dimension1, + std::size_t Dimension2 > class rad_rotate_transformer - : public ublas_transformer + : public ublas_transformer { - // Angle has type of coordinate type, but at least a double - typedef typename select_most_precise - < - typename select_coordinate_type::type, - double - >::type angle_type; - public : - inline rad_rotate_transformer(angle_type const& angle) - : ublas_transformer( + inline rad_rotate_transformer(CalculationType const& angle) + : ublas_transformer( cos(angle), sin(angle), 0, -sin(angle), cos(angle), 0, 0, 0, 1) @@ -385,29 +363,27 @@ public : \details Rotate rotates a geometry of specified angle about a fixed point (e.g. origin). \see http://en.wikipedia.org/wiki/Rotation_%28mathematics%29 \ingroup strategies -\tparam P1 first point type -\tparam P2 second point type \tparam DegreeOrRadian degree/or/radian, type of rotation angle specification \note A single angle is needed to specify a rotation in 2D. Not yet in 3D, the 3D version requires special things to allow for rotation around X, Y, Z or arbitrary axis. \todo The 3D version will not compile. */ -template -class rotate_transformer : public detail::rad_rotate_transformer +template +< + typename DegreeOrRadian, + typename CalculationType, + std::size_t Dimension1, + std::size_t Dimension2 +> +class rotate_transformer : public detail::rad_rotate_transformer { - // Angle has type of coordinate type, but at least a double - typedef typename select_most_precise - < - typename select_coordinate_type::type, - double - >::type angle_type; public : - inline rotate_transformer(angle_type const& angle) + inline rotate_transformer(CalculationType const& angle) : detail::rad_rotate_transformer < - P1, P2 + CalculationType, Dimension1, Dimension2 >(detail::as_radian::get(angle)) {} }; diff --git a/test/multi/algorithms/multi_transform.cpp b/test/multi/algorithms/multi_transform.cpp index dddb01c45..9c0002583 100644 --- a/test/multi/algorithms/multi_transform.cpp +++ b/test/multi/algorithms/multi_transform.cpp @@ -39,12 +39,13 @@ template void test_transform(std::string const& wkt, std::string const& expected) { - typedef typename bg::point_type::type point_type; + typedef typename bg::coordinate_type::type coordinate_type; + const std::size_t dim = bg::dimension::value; Geometry geometry_in, geometry_out; bg::read_wkt(wkt, geometry_in); bg::transform(geometry_in, geometry_out, - bg::strategy::transform::scale_transformer(2, 2)); + bg::strategy::transform::scale_transformer(2, 2)); std::ostringstream detected; detected << bg::wkt(geometry_out); BOOST_CHECK_EQUAL(detected.str(), expected); diff --git a/test/strategies/transformer.cpp b/test/strategies/transformer.cpp index b469e08cc..5cdc567e6 100644 --- a/test/strategies/transformer.cpp +++ b/test/strategies/transformer.cpp @@ -34,7 +34,10 @@ BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian) template void check_inverse(P const& p, T const& trans) { - bg::strategy::transform::inverse_transformer inverse(trans); + typedef typename bg::coordinate_type

::type coordinate_type; + const std::size_t dim = bg::dimension

::value; + + bg::strategy::transform::inverse_transformer inverse(trans); P i; bg::transform(p, i, inverse); @@ -46,11 +49,14 @@ void check_inverse(P const& p, T const& trans) template void test_all() { + typedef typename bg::coordinate_type

::type coordinate_type; + const std::size_t dim = bg::dimension

::value; + P p; bg::assign_values(p, 1, 1); { - bg::strategy::transform::translate_transformer trans(1, 1); + bg::strategy::transform::translate_transformer trans(1, 1); P tp; bg::transform(p, tp, trans); @@ -61,7 +67,7 @@ void test_all() } { - bg::strategy::transform::scale_transformer trans(10, 10); + bg::strategy::transform::scale_transformer trans(10, 10); P tp; bg::transform(p, tp, trans); @@ -72,7 +78,7 @@ void test_all() } { - bg::strategy::transform::rotate_transformer trans(90.0); + bg::strategy::transform::rotate_transformer trans(90.0); P tp; bg::transform(p, tp, trans); @@ -83,7 +89,7 @@ void test_all() { // Map from 0,0,2,2 to 0,0,500,500 - bg::strategy::transform::map_transformer trans + bg::strategy::transform::map_transformer trans ( 0.0, 0.0, 2.0, 2.0, 500, 500 );