1 // Boost.Geometry Index
2 //
3 // This view makes possible to treat some simple primitives as its bounding geometry
4 // e.g. box, nsphere, etc.
5 //
6 // Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland.
7 //
8 // Use, modification and distribution is subject to the Boost Software License,
9 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
10 // http://www.boost.org/LICENSE_1_0.txt)
11 
12 #ifndef BOOST_GEOMETRY_INDEX_DETAIL_BOUNDED_VIEW_HPP
13 #define BOOST_GEOMETRY_INDEX_DETAIL_BOUNDED_VIEW_HPP
14 
15 #include <boost/geometry/algorithms/envelope.hpp>
16 
17 namespace boost { namespace geometry {
18 
19 namespace index { namespace detail {
20 
21 template <typename Geometry,
22           typename BoundingGeometry,
23           typename Tag = typename geometry::tag<Geometry>::type,
24           typename BoundingTag = typename geometry::tag<BoundingGeometry>::type,
25           typename CSystem = typename geometry::coordinate_system<Geometry>::type>
26 struct bounded_view
27 {
28     BOOST_MPL_ASSERT_MSG(
29         (false),
30         NOT_IMPLEMENTED_FOR_THOSE_GEOMETRIES,
31         (BoundingTag, Tag));
32 };
33 
34 
35 // Segment -> Box
36 
37 template <typename Segment, typename Box>
38 struct bounded_view<Segment, Box, segment_tag, box_tag, cs::cartesian>
39 {
40 public:
41     typedef typename geometry::coordinate_type<Box>::type coordinate_type;
42 
bounded_viewboost::geometry::index::detail::bounded_view43     explicit bounded_view(Segment const& segment)
44         : m_segment(segment)
45     {}
46 
47     template <std::size_t Dimension>
get_minboost::geometry::index::detail::bounded_view48     inline coordinate_type get_min() const
49     {
50         return boost::numeric_cast<coordinate_type>(
51                 (std::min)( geometry::get<0, Dimension>(m_segment),
52                             geometry::get<1, Dimension>(m_segment) ) );
53     }
54 
55     template <std::size_t Dimension>
get_maxboost::geometry::index::detail::bounded_view56     inline coordinate_type get_max() const
57     {
58         return boost::numeric_cast<coordinate_type>(
59                 (std::max)( geometry::get<0, Dimension>(m_segment),
60                             geometry::get<1, Dimension>(m_segment) ) );
61     }
62 
63 private:
64     Segment const& m_segment;
65 };
66 
67 template <typename Segment, typename Box, typename CSystem>
68 struct bounded_view<Segment, Box, segment_tag, box_tag, CSystem>
69 {
70 public:
71     typedef typename geometry::coordinate_type<Box>::type coordinate_type;
72 
bounded_viewboost::geometry::index::detail::bounded_view73     explicit bounded_view(Segment const& segment)
74     {
75         geometry::envelope(segment, m_box);
76     }
77 
78     template <std::size_t Dimension>
get_minboost::geometry::index::detail::bounded_view79     inline coordinate_type get_min() const
80     {
81         return geometry::get<min_corner, Dimension>(m_box);
82     }
83 
84     template <std::size_t Dimension>
get_maxboost::geometry::index::detail::bounded_view85     inline coordinate_type get_max() const
86     {
87         return geometry::get<max_corner, Dimension>(m_box);
88     }
89 
90 private:
91     Box m_box;
92 };
93 
94 // Box -> Box
95 
96 template <typename BoxIn, typename Box, typename CSystem>
97 struct bounded_view<BoxIn, Box, box_tag, box_tag, CSystem>
98 {
99 public:
100     typedef typename geometry::coordinate_type<Box>::type coordinate_type;
101 
bounded_viewboost::geometry::index::detail::bounded_view102     explicit bounded_view(BoxIn const& box)
103         : m_box(box)
104     {}
105 
106     template <std::size_t Dimension>
get_minboost::geometry::index::detail::bounded_view107     inline coordinate_type get_min() const
108     {
109         return boost::numeric_cast<coordinate_type>(
110                 geometry::get<min_corner, Dimension>(m_box) );
111     }
112 
113     template <std::size_t Dimension>
get_maxboost::geometry::index::detail::bounded_view114     inline coordinate_type get_max() const
115     {
116         return boost::numeric_cast<coordinate_type>(
117                 geometry::get<max_corner, Dimension>(m_box) );
118     }
119 
120 private:
121     BoxIn const& m_box;
122 };
123 
124 // Point -> Box
125 
126 template <typename Point, typename Box, typename CSystem>
127 struct bounded_view<Point, Box, point_tag, box_tag, CSystem>
128 {
129 public:
130     typedef typename geometry::coordinate_type<Box>::type coordinate_type;
131 
bounded_viewboost::geometry::index::detail::bounded_view132     explicit bounded_view(Point const& point)
133         : m_point(point)
134     {}
135 
136     template <std::size_t Dimension>
get_minboost::geometry::index::detail::bounded_view137     inline coordinate_type get_min() const
138     {
139         return boost::numeric_cast<coordinate_type>(
140                 geometry::get<Dimension>(m_point) );
141     }
142 
143     template <std::size_t Dimension>
get_maxboost::geometry::index::detail::bounded_view144     inline coordinate_type get_max() const
145     {
146         return boost::numeric_cast<coordinate_type>(
147                 geometry::get<Dimension>(m_point) );
148     }
149 
150 private:
151     Point const& m_point;
152 };
153 
154 }} // namespace index::detail
155 
156 // XXX -> Box
157 
158 #ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
159 namespace traits
160 {
161 
162 template <typename Geometry, typename Box, typename Tag, typename CSystem>
163 struct tag< index::detail::bounded_view<Geometry, Box, Tag, box_tag, CSystem> >
164 {
165     typedef box_tag type;
166 };
167 
168 template <typename Geometry, typename Box, typename Tag, typename CSystem>
169 struct point_type< index::detail::bounded_view<Geometry, Box, Tag, box_tag, CSystem> >
170 {
171     typedef typename point_type<Box>::type type;
172 };
173 
174 template <typename Geometry, typename Box, typename Tag, typename CSystem, std::size_t Dimension>
175 struct indexed_access<index::detail::bounded_view<Geometry, Box, Tag, box_tag, CSystem>,
176                       min_corner, Dimension>
177 {
178     typedef index::detail::bounded_view<Geometry, Box, Tag, box_tag, CSystem> box_type;
179     typedef typename geometry::coordinate_type<Box>::type coordinate_type;
180 
getboost::geometry::traits::indexed_access181     static inline coordinate_type get(box_type const& b)
182     {
183         return b.template get_min<Dimension>();
184     }
185 
186     //static inline void set(box_type & b, coordinate_type const& value)
187     //{
188     //    BOOST_GEOMETRY_INDEX_ASSERT(false, "unable to modify a box through view");
189     //}
190 };
191 
192 template <typename Geometry, typename Box, typename Tag, typename CSystem, std::size_t Dimension>
193 struct indexed_access<index::detail::bounded_view<Geometry, Box, Tag, box_tag, CSystem>,
194                       max_corner, Dimension>
195 {
196     typedef index::detail::bounded_view<Geometry, Box, Tag, box_tag, CSystem> box_type;
197     typedef typename geometry::coordinate_type<Box>::type coordinate_type;
198 
getboost::geometry::traits::indexed_access199     static inline coordinate_type get(box_type const& b)
200     {
201         return b.template get_max<Dimension>();
202     }
203 
204     //static inline void set(box_type & b, coordinate_type const& value)
205     //{
206     //    BOOST_GEOMETRY_INDEX_ASSERT(false, "unable to modify a box through view");
207     //}
208 };
209 
210 } // namespace traits
211 #endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
212 
213 }} // namespace boost::geometry
214 
215 #endif // BOOST_GEOMETRY_INDEX_DETAIL_BOUNDED_VIEW_HPP
216