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 // This file was modified by Oracle on 2019. 9 // Modifications copyright (c) 2019 Oracle and/or its affiliates. 10 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle 11 // 12 // Use, modification and distribution is subject to the Boost Software License, 13 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 14 // http://www.boost.org/LICENSE_1_0.txt) 15 16 #ifndef BOOST_GEOMETRY_INDEX_DETAIL_BOUNDED_VIEW_HPP 17 #define BOOST_GEOMETRY_INDEX_DETAIL_BOUNDED_VIEW_HPP 18 19 #include <boost/mpl/assert.hpp> 20 21 #include <boost/geometry/algorithms/envelope.hpp> 22 23 #include <boost/geometry/strategies/index.hpp> 24 25 namespace boost { namespace geometry { 26 27 namespace index { namespace detail { 28 29 30 template <typename Geometry, typename BoundingGeometry, typename Strategy> 31 struct bounded_view_base_cs_tag 32 { 33 typedef typename Strategy::cs_tag type; 34 }; 35 36 template <typename Geometry, typename BoundingGeometry> 37 struct bounded_view_base_cs_tag<Geometry, BoundingGeometry, default_strategy> 38 : geometry::cs_tag<Geometry> 39 {}; 40 41 42 template 43 < 44 typename Geometry, 45 typename BoundingGeometry, 46 typename Strategy, 47 typename Tag = typename geometry::tag<Geometry>::type, 48 typename BoundingTag = typename geometry::tag<BoundingGeometry>::type, 49 typename CSTag = typename bounded_view_base_cs_tag 50 < 51 Geometry, BoundingGeometry, Strategy 52 >::type 53 > 54 struct bounded_view_base 55 { 56 BOOST_MPL_ASSERT_MSG( 57 (false), 58 NOT_IMPLEMENTED_FOR_THOSE_GEOMETRIES, 59 (types<Tag, BoundingTag, CSTag>)); 60 }; 61 62 63 // Segment -> Box 64 65 template <typename Segment, typename Box, typename Strategy> 66 struct bounded_view_base<Segment, Box, Strategy, segment_tag, box_tag, cartesian_tag> 67 { 68 public: 69 typedef typename geometry::coordinate_type<Box>::type coordinate_type; 70 bounded_view_baseboost::geometry::index::detail::bounded_view_base71 bounded_view_base(Segment const& segment, Strategy const& ) 72 : m_segment(segment) 73 {} 74 75 template <std::size_t Dimension> get_minboost::geometry::index::detail::bounded_view_base76 inline coordinate_type get_min() const 77 { 78 return boost::numeric_cast<coordinate_type>( 79 (std::min)( geometry::get<0, Dimension>(m_segment), 80 geometry::get<1, Dimension>(m_segment) ) ); 81 } 82 83 template <std::size_t Dimension> get_maxboost::geometry::index::detail::bounded_view_base84 inline coordinate_type get_max() const 85 { 86 return boost::numeric_cast<coordinate_type>( 87 (std::max)( geometry::get<0, Dimension>(m_segment), 88 geometry::get<1, Dimension>(m_segment) ) ); 89 } 90 91 private: 92 Segment const& m_segment; 93 }; 94 95 template <typename Segment, typename Box, typename Strategy, typename CSTag> 96 struct bounded_view_base<Segment, Box, Strategy, segment_tag, box_tag, CSTag> 97 { 98 template <typename S> envelopeboost::geometry::index::detail::bounded_view_base99 inline void envelope(Segment const& segment, S const& strategy) 100 { 101 geometry::envelope(segment, m_box, 102 strategy.get_envelope_segment_strategy()); 103 } 104 envelopeboost::geometry::index::detail::bounded_view_base105 inline void envelope(Segment const& segment, default_strategy const& ) 106 { 107 geometry::envelope(segment, m_box); 108 } 109 110 public: 111 typedef typename geometry::coordinate_type<Box>::type coordinate_type; 112 bounded_view_baseboost::geometry::index::detail::bounded_view_base113 bounded_view_base(Segment const& segment, Strategy const& strategy) 114 { 115 envelope(segment, strategy); 116 } 117 118 template <std::size_t Dimension> get_minboost::geometry::index::detail::bounded_view_base119 inline coordinate_type get_min() const 120 { 121 return geometry::get<min_corner, Dimension>(m_box); 122 } 123 124 template <std::size_t Dimension> get_maxboost::geometry::index::detail::bounded_view_base125 inline coordinate_type get_max() const 126 { 127 return geometry::get<max_corner, Dimension>(m_box); 128 } 129 130 private: 131 Box m_box; 132 }; 133 134 // Box -> Box 135 136 template <typename BoxIn, typename Box, typename Strategy, typename CSTag> 137 struct bounded_view_base<BoxIn, Box, Strategy, box_tag, box_tag, CSTag> 138 { 139 public: 140 typedef typename geometry::coordinate_type<Box>::type coordinate_type; 141 bounded_view_baseboost::geometry::index::detail::bounded_view_base142 bounded_view_base(BoxIn const& box, Strategy const& ) 143 : m_box(box) 144 {} 145 146 template <std::size_t Dimension> get_minboost::geometry::index::detail::bounded_view_base147 inline coordinate_type get_min() const 148 { 149 return boost::numeric_cast<coordinate_type>( 150 geometry::get<min_corner, Dimension>(m_box) ); 151 } 152 153 template <std::size_t Dimension> get_maxboost::geometry::index::detail::bounded_view_base154 inline coordinate_type get_max() const 155 { 156 return boost::numeric_cast<coordinate_type>( 157 geometry::get<max_corner, Dimension>(m_box) ); 158 } 159 160 private: 161 BoxIn const& m_box; 162 }; 163 164 // Point -> Box 165 166 template <typename Point, typename Box, typename Strategy, typename CSTag> 167 struct bounded_view_base<Point, Box, Strategy, point_tag, box_tag, CSTag> 168 { 169 public: 170 typedef typename geometry::coordinate_type<Box>::type coordinate_type; 171 bounded_view_baseboost::geometry::index::detail::bounded_view_base172 bounded_view_base(Point const& point, Strategy const& ) 173 : m_point(point) 174 {} 175 176 template <std::size_t Dimension> get_minboost::geometry::index::detail::bounded_view_base177 inline coordinate_type get_min() const 178 { 179 return boost::numeric_cast<coordinate_type>( 180 geometry::get<Dimension>(m_point) ); 181 } 182 183 template <std::size_t Dimension> get_maxboost::geometry::index::detail::bounded_view_base184 inline coordinate_type get_max() const 185 { 186 return boost::numeric_cast<coordinate_type>( 187 geometry::get<Dimension>(m_point) ); 188 } 189 190 private: 191 Point const& m_point; 192 }; 193 194 195 template <typename Geometry, 196 typename BoundingGeometry, 197 typename Strategy, 198 typename Tag = typename geometry::tag<Geometry>::type, 199 typename BoundingTag = typename geometry::tag<BoundingGeometry>::type> 200 struct bounded_view 201 : bounded_view_base<Geometry, BoundingGeometry, Strategy> 202 { 203 typedef bounded_view_base<Geometry, BoundingGeometry, Strategy> base_type; 204 bounded_viewboost::geometry::index::detail::bounded_view205 bounded_view(Geometry const& geometry, Strategy const& strategy) 206 : base_type(geometry, strategy) 207 {} 208 }; 209 210 template <typename Geometry, 211 typename BoundingGeometry, 212 typename Tag, 213 typename BoundingTag> 214 struct bounded_view<Geometry, BoundingGeometry, default_strategy, Tag, BoundingTag> 215 : bounded_view_base 216 < 217 Geometry, 218 BoundingGeometry, 219 typename strategy::index::services::default_strategy<Geometry>::type 220 > 221 { 222 typedef typename strategy::index::services::default_strategy 223 < 224 Geometry 225 >::type strategy_type; 226 227 typedef bounded_view_base 228 < 229 Geometry, 230 BoundingGeometry, 231 strategy_type 232 > base_type; 233 bounded_viewboost::geometry::index::detail::bounded_view234 explicit bounded_view(Geometry const& geometry, default_strategy const& ) 235 : base_type(geometry, strategy_type()) 236 {} 237 }; 238 239 240 }} // namespace index::detail 241 242 // XXX -> Box 243 244 #ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS 245 namespace traits 246 { 247 248 template <typename Geometry, typename Box, typename Strategy, typename Tag> 249 struct tag< index::detail::bounded_view<Geometry, Box, Strategy, Tag, box_tag> > 250 { 251 typedef box_tag type; 252 }; 253 254 template <typename Geometry, typename Box, typename Strategy, typename Tag> 255 struct point_type< index::detail::bounded_view<Geometry, Box, Strategy, Tag, box_tag> > 256 { 257 typedef typename point_type<Box>::type type; 258 }; 259 260 template <typename Geometry, typename Box, typename Strategy, typename Tag, std::size_t Dimension> 261 struct indexed_access<index::detail::bounded_view<Geometry, Box, Strategy, Tag, box_tag>, 262 min_corner, Dimension> 263 { 264 typedef index::detail::bounded_view<Geometry, Box, Strategy, Tag, box_tag> box_type; 265 typedef typename geometry::coordinate_type<Box>::type coordinate_type; 266 getboost::geometry::traits::indexed_access267 static inline coordinate_type get(box_type const& b) 268 { 269 return b.template get_min<Dimension>(); 270 } 271 272 //static inline void set(box_type & b, coordinate_type const& value) 273 //{ 274 // BOOST_GEOMETRY_INDEX_ASSERT(false, "unable to modify a box through view"); 275 //} 276 }; 277 278 template <typename Geometry, typename Box, typename Strategy, typename Tag, std::size_t Dimension> 279 struct indexed_access<index::detail::bounded_view<Geometry, Box, Strategy, Tag, box_tag>, 280 max_corner, Dimension> 281 { 282 typedef index::detail::bounded_view<Geometry, Box, Strategy, Tag, box_tag> box_type; 283 typedef typename geometry::coordinate_type<Box>::type coordinate_type; 284 getboost::geometry::traits::indexed_access285 static inline coordinate_type get(box_type const& b) 286 { 287 return b.template get_max<Dimension>(); 288 } 289 290 //static inline void set(box_type & b, coordinate_type const& value) 291 //{ 292 // BOOST_GEOMETRY_INDEX_ASSERT(false, "unable to modify a box through view"); 293 //} 294 }; 295 296 } // namespace traits 297 #endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS 298 299 }} // namespace boost::geometry 300 301 #endif // BOOST_GEOMETRY_INDEX_DETAIL_BOUNDED_VIEW_HPP 302