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