x02_gd_example.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. //
  3. // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
  4. // Use, modification and distribution is subject to the Boost Software License,
  5. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. // GD example
  9. // GD is a well-known and often used graphic library to write GIF (and other formats)
  10. // To build and run this example:
  11. // 1) download GD from http://www.libgd.org (currently gd-2.0.35 is assumed)
  12. // 2) add 11 files
  13. // gd.c, gd_gd.c, gd_gif_out.c, gd_io*.c, gd_security.c, gd_topal.c, gdhelpers.c, gdtables.c
  14. // to the project or makefile or jamfile
  15. // 3) for windows, add define NONDLL to indicate GD is not used as a DLL
  16. // (Note that steps 2 and 3 are done in the MSVC gd_example project file and property sheets)
  17. #include <cmath>
  18. #include <cstdio>
  19. #include <vector>
  20. #include <fstream>
  21. #include <sstream>
  22. #include <boost/foreach.hpp>
  23. #include <boost/geometry.hpp>
  24. #include <boost/geometry/geometries/multi_polygon.hpp>
  25. #include <boost/geometry/extensions/gis/latlong/latlong.hpp>
  26. #include <boost/geometry/extensions/gis/geographic/strategies/area_huiller_earth.hpp>
  27. #include <gd.h>
  28. namespace bg = boost::geometry;
  29. // ----------------------------------------------------------------------------
  30. // Read an ASCII file containing WKT's
  31. // (note this function is shared by various examples)
  32. // ----------------------------------------------------------------------------
  33. template <typename Geometry>
  34. inline void read_wkt(std::string const& filename, std::vector<Geometry>& geometries)
  35. {
  36. std::ifstream cpp_file(filename.c_str());
  37. if (cpp_file.is_open())
  38. {
  39. while (! cpp_file.eof() )
  40. {
  41. std::string line;
  42. std::getline(cpp_file, line);
  43. if (! line.empty())
  44. {
  45. Geometry geometry;
  46. bg::read_wkt(line, geometry);
  47. geometries.push_back(geometry);
  48. }
  49. }
  50. }
  51. }
  52. int main()
  53. {
  54. // Adapt if necessary
  55. std::string filename = "../data/world.wkt";
  56. // The world is measured in latlong (degrees), so latlong is appropriate.
  57. // We ignore holes in this sample (below)
  58. typedef bg::model::ll::point<bg::degree> point_type;
  59. typedef bg::model::polygon<point_type> polygon_type;
  60. typedef bg::model::multi_polygon<polygon_type> country_type;
  61. std::vector<country_type> countries;
  62. // Read (for example) world countries
  63. read_wkt(filename, countries);
  64. // Create a GD image.
  65. // A world map, as world.shp, is usually mapped in latitude-longitude (-180..180 and -90..90)
  66. // For this example we use a very simple "transformation"
  67. // mapping to 0..720 and 0..360
  68. const double factor = 2.0;
  69. gdImagePtr im = gdImageCreateTrueColor(int(360 * factor), int(180 * factor));
  70. // Allocate three colors
  71. int blue = gdImageColorResolve(im, 0, 52, 255);
  72. int green = gdImageColorResolve(im, 0, 255, 0);
  73. int black = gdImageColorResolve(im, 0, 0, 0);
  74. // Paint background in blue
  75. gdImageFilledRectangle(im, 0, 0, im->sx, im->sy, blue);
  76. // Paint all countries in green
  77. BOOST_FOREACH(country_type const& country, countries)
  78. {
  79. BOOST_FOREACH(polygon_type const& polygon, country)
  80. {
  81. // Ignore holes, so take only exterior ring
  82. bg::model::ring<point_type> const& ring = bg::exterior_ring(polygon);
  83. // If wished, suppress too small polygons.
  84. // (Note that even in latlong, area is calculated in square meters)
  85. double const a = bg::area(ring);
  86. if (std::fabs(a) > 5000.0e6)
  87. {
  88. int const n = ring.size();
  89. gdPoint* points = new gdPoint[n];
  90. for (int i = 0; i < n; i++)
  91. {
  92. // Translate lon/lat or x/y to GD x/y points
  93. points[i].x = int(factor * (bg::get<0>(ring[i]) + 180.0));
  94. points[i].y = im->sy - int(factor * (bg::get<1>(ring[i]) + 90.0));
  95. }
  96. // Draw the polygon...
  97. gdImageFilledPolygon(im, points, n, green);
  98. // .. and the outline in black...
  99. gdImagePolygon(im, points, n, black);
  100. delete[] points;
  101. }
  102. }
  103. }
  104. // Use GD to create a GIF file
  105. std::FILE* out = std::fopen("world.gif", "wb");
  106. if (out != NULL)
  107. {
  108. gdImageGif(im, out);
  109. std::fclose(out);
  110. }
  111. gdImageDestroy(im);
  112. return 0;
  113. }