/Src/Dependencies/Boost/libs/geometry/example/06_b_transformation_example.cpp

http://hadesmem.googlecode.com/ · C++ · 170 lines · 126 code · 28 blank · 16 comment · 1 complexity · 787c2cbaea8d5c20e08b7b3f9c91d4cc MD5 · raw file

  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Example: Affine Transformation (translate, scale, rotate)
  3. //
  4. // Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
  5. //
  6. // Use, modification and distribution is subject to the Boost Software License,
  7. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. #include <ctime> // for std::time
  10. #include <algorithm>
  11. #include <fstream>
  12. #include <iostream>
  13. #include <limits>
  14. #include <sstream>
  15. #include <boost/geometry/geometry.hpp>
  16. #include <boost/geometry/geometries/point_xy.hpp>
  17. #include <boost/geometry/geometries/polygon.hpp>
  18. #include <boost/geometry/algorithms/centroid.hpp>
  19. #include <boost/geometry/strategies/transform.hpp>
  20. #include <boost/geometry/strategies/transform/matrix_transformers.hpp>
  21. #include <boost/geometry/domains/gis/io/wkt/read_wkt.hpp>
  22. #if defined(HAVE_SVG)
  23. # include <boost/geometry/extensions/io/svg/write_svg.hpp>
  24. #endif
  25. #include <boost/bind.hpp>
  26. #include <boost/random.hpp>
  27. #include <boost/range.hpp>
  28. #include <boost/shared_ptr.hpp>
  29. using namespace boost::geometry;
  30. struct random_style
  31. {
  32. random_style()
  33. : rng(static_cast<int>(std::time(0))), dist(0, 255), colour(rng, dist)
  34. {}
  35. std::string fill(double opacity = 1)
  36. {
  37. std::ostringstream oss;
  38. oss << "fill:rgba(" << colour() << "," << colour() << "," << colour() << "," << opacity << ");";
  39. return oss.str();
  40. }
  41. std::string stroke(int width, double opacity = 1)
  42. {
  43. std::ostringstream oss;
  44. oss << "stroke:rgba(" << colour() << "," << colour() << "," << colour() << "," << opacity << ");";
  45. oss << "stroke-width:" << width << ";";
  46. return oss.str();
  47. }
  48. template <typename T>
  49. std::string text(T x, T y, std::string const& text)
  50. {
  51. std::ostringstream oss;
  52. oss << "<text x=\"" << static_cast<int>(x) - 90 << "\" y=\"" << static_cast<int>(y) << "\" font-family=\"Verdana\">" << text << "</text>";
  53. return oss.str();
  54. }
  55. boost::mt19937 rng;
  56. boost::uniform_int<> dist;
  57. boost::variate_generator<boost::mt19937&, boost::uniform_int<> > colour;
  58. };
  59. template <typename OutputStream>
  60. struct svg_output
  61. {
  62. svg_output(OutputStream& os, double opacity = 1) : os(os), opacity(opacity)
  63. {
  64. os << "<?xml version=\"1.0\" standalone=\"no\"?>\n"
  65. << "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n"
  66. << "\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n"
  67. << "<svg width=\"100%\" height=\"100%\" version=\"1.1\"\n"
  68. << "xmlns=\"http://www.w3.org/2000/svg\">" << std::endl;
  69. }
  70. ~svg_output()
  71. {
  72. os << "</svg>" << std::endl;
  73. }
  74. template <typename G>
  75. void put(G const& g, std::string const& label)
  76. {
  77. std::string style_str(style.fill(opacity) + style.stroke(5, opacity));
  78. #if defined(HAVE_SVG)
  79. os << boost::geometry::svg(g, style_str) << std::endl;
  80. #endif
  81. if (!label.empty())
  82. {
  83. typename point_type<G>::type c;
  84. centroid(g, c);
  85. os << style.text(static_cast<int>(get<0>(c)), static_cast<int>(get<1>(c)), label);
  86. }
  87. }
  88. private:
  89. OutputStream& os;
  90. double opacity;
  91. random_style style;
  92. };
  93. int main()
  94. {
  95. using namespace boost::geometry::strategy::transform;
  96. typedef boost::geometry::model::d2::point_xy<double> point_2d;
  97. try
  98. {
  99. std::string file("06_b_transformation_example.svg");
  100. std::ofstream ofs(file.c_str());
  101. svg_output<std::ofstream> svg(ofs, 0.5);
  102. // G1 - create subject for affine transformations
  103. model::polygon<point_2d> g1;
  104. read_wkt("POLYGON((50 250, 400 250, 150 50, 50 250))", g1);
  105. std::clog << "source box:\t" << boost::geometry::dsv(g1) << std::endl;
  106. svg.put(g1, "g1");
  107. // G1 - Translate -> G2
  108. translate_transformer<point_2d, point_2d> translate(0, 250);
  109. model::polygon<point_2d> g2;
  110. transform(g1, g2, translate);
  111. std::clog << "translated:\t" << boost::geometry::dsv(g2) << std::endl;
  112. svg.put(g2, "g2=g1.translate(0,250)");
  113. // G2 - Scale -> G3
  114. scale_transformer<point_2d, point_2d> scale(0.5, 0.5);
  115. model::polygon<point_2d> g3;
  116. transform(g2, g3, scale);
  117. std::clog << "scaled:\t" << boost::geometry::dsv(g3) << std::endl;
  118. svg.put(g3, "g3=g2.scale(0.5,0.5)");
  119. // G3 - Combine rotate and translate -> G4
  120. rotate_transformer<point_2d, point_2d, degree> rotate(45);
  121. // Compose matrix for the two transformation
  122. // Create transformer attached to the transformation matrix
  123. ublas_transformer<point_2d, point_2d, 2, 2>
  124. combined(boost::numeric::ublas::prod(rotate.matrix(), translate.matrix()));
  125. //combined(rotate.matrix());
  126. // Apply transformation to subject geometry point-by-point
  127. model::polygon<point_2d> g4;
  128. transform(g3, g4, combined);
  129. std::clog << "rotated & translated:\t" << boost::geometry::dsv(g4) << std::endl;
  130. svg.put(g4, "g4 = g3.(rotate(45) * translate(0,250))");
  131. std::clog << "Saved SVG file:\t" << file << std::endl;
  132. }
  133. catch (std::exception const& e)
  134. {
  135. std::cerr << e.what() << std::endl;
  136. }
  137. catch (...)
  138. {
  139. std::cerr << "unknown error" << std::endl;
  140. }
  141. return 0;
  142. }