1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 
3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
4 // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
5 // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
6 
7 // Use, modification and distribution is subject to the Boost Software License,
8 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
10 //
11 // Custom Polygon Example
12 #include <iostream>
13 
14 #include <boost/geometry/geometry.hpp>
15 
16 #include <boost/geometry/geometries/register/point.hpp>
17 #include <boost/geometry/geometries/register/ring.hpp>
18 
19 
20 struct my_point
21 {
my_pointmy_point22     my_point(double an_x = 0, double an_y = 0)
23         : x(an_x)
24         , y(an_y)
25     {}
26 
27     double x, y;
28 };
29 
30 struct my_ring : std::deque<my_point>
31 {};
32 
33 // Define a struct of a polygon, having always two holes
34 // (of course this can be implemented differently, usually
35 // with a vector or deque, but it is just an exampe)
36 struct my_polygon
37 {
38     // required for a polygon: an outer ring...
39     my_ring boundary;
40     // ... and a Boost.Range compatible inner ring collection
41     boost::array<my_ring, 2> holes;
42 
43     // just for the sample
44     std::string name;
45 
my_polygonmy_polygon46     my_polygon(std::string const& n = "") : name(n) {}
47 };
48 
49 
50 // We can conveniently use macro's to register point and ring
51 BOOST_GEOMETRY_REGISTER_POINT_2D(my_point, double, cs::cartesian, x, y)
52 BOOST_GEOMETRY_REGISTER_RING(my_ring)
53 
54 
55 
56 // There is currently no registration macro for polygons
57 // and besides that a boost::array<T,N> in a macro would
58 // be very specific, so we show it "by hand":
59 namespace boost { namespace geometry { namespace traits
60 {
61 
62 template<> struct tag<my_polygon> { typedef polygon_tag type; };
63 template<> struct ring_const_type<my_polygon> { typedef my_ring const& type; };
64 template<> struct ring_mutable_type<my_polygon> { typedef my_ring& type; };
65 
66 template<> struct interior_const_type<my_polygon>
67 {
68     typedef boost::array<my_ring, 2> const& type;
69 };
70 
71 template<> struct interior_mutable_type<my_polygon>
72 {
73     typedef boost::array<my_ring, 2>& type;
74 };
75 
76 template<> struct exterior_ring<my_polygon>
77 {
getboost::geometry::traits::exterior_ring78     static my_ring& get(my_polygon& p)
79     {
80         return p.boundary;
81     }
82 
getboost::geometry::traits::exterior_ring83     static my_ring const& get(my_polygon const& p)
84     {
85         return p.boundary;
86     }
87 };
88 
89 template<> struct interior_rings<my_polygon>
90 {
91     typedef boost::array<my_ring, 2> holes_type;
92 
getboost::geometry::traits::interior_rings93     static holes_type& get(my_polygon& p)
94     {
95         return p.holes;
96     }
97 
getboost::geometry::traits::interior_rings98     static holes_type const& get(my_polygon const& p)
99     {
100         return p.holes;
101     }
102 };
103 
104 }}} // namespace boost::geometry::traits
105 
106 
107 
main()108 int main()
109 {
110     my_polygon p1("my polygon");
111 
112     // Fill it the my-way, triangle
113     p1.boundary.push_back(my_point(2, 0));
114     p1.boundary.push_back(my_point(1, 5));
115     p1.boundary.push_back(my_point(7, 6));
116     p1.boundary.push_back(my_point(2, 0));
117 
118     // Triangle
119     p1.holes[0].push_back(my_point(2, 1));
120     p1.holes[0].push_back(my_point(2.4, 2));
121     p1.holes[0].push_back(my_point(1.9, 2));
122     p1.holes[0].push_back(my_point(2, 1));
123 
124     // Box
125     p1.holes[1].push_back(my_point(3, 3));
126     p1.holes[1].push_back(my_point(4, 3));
127     p1.holes[1].push_back(my_point(4, 4));
128     p1.holes[1].push_back(my_point(3, 4));
129     p1.holes[1].push_back(my_point(3, 3));
130 
131     std::cout << "Representation of " << p1.name << ": "
132         << boost::geometry::dsv(p1) << std::endl;
133     std::cout << "Area of " << p1.name << ": "
134         << boost::geometry::area(p1) << std::endl;
135     std::cout << "Perimeter of " << p1.name << ": "
136         << boost::geometry::perimeter(p1) << std::endl;
137     std::cout << "Centroid of " << p1.name << ": "
138         << boost::geometry::dsv(boost::geometry::return_centroid<my_point>(p1)) << std::endl;
139 
140     return 0;
141 }
142