Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r73177 - in trunk/boost/geometry: algorithms core multi/algorithms multi/core strategies strategies/agnostic strategies/cartesian strategies/concepts util
From: barend.gehrels_at_[hidden]
Date: 2011-07-17 08:26:03


Author: barendgehrels
Date: 2011-07-17 08:26:01 EDT (Sun, 17 Jul 2011)
New Revision: 73177
URL: http://svn.boost.org/trac/boost/changeset/73177

Log:
Added a "covered_by" algorithm (= within or on border)
Revised point-in-box, box-in-box, now with strategies
Therefore, revised within strategy.
Also adapted concept for within, and refactored getting parameters into parameter_type_of (also used by distance concept)
To avoid specifying default strategies again and again for all spherical coordinate systems, used the spherical_tag as the parent for spherical_polar_tag, spherical_equatorial_tag, geographic_tag

Added:
   trunk/boost/geometry/algorithms/covered_by.hpp (contents, props changed)
   trunk/boost/geometry/multi/algorithms/covered_by.hpp (contents, props changed)
   trunk/boost/geometry/strategies/agnostic/point_in_box_by_side.hpp (contents, props changed)
   trunk/boost/geometry/strategies/cartesian/box_in_box.hpp (contents, props changed)
   trunk/boost/geometry/strategies/cartesian/point_in_box.hpp (contents, props changed)
   trunk/boost/geometry/strategies/covered_by.hpp (contents, props changed)
   trunk/boost/geometry/util/parameter_type_of.hpp (contents, props changed)
Text files modified:
   trunk/boost/geometry/algorithms/within.hpp | 410 ++++++++-------------------------------
   trunk/boost/geometry/core/tags.hpp | 16 +
   trunk/boost/geometry/multi/algorithms/within.hpp | 43 ++-
   trunk/boost/geometry/multi/core/tags.hpp | 2
   trunk/boost/geometry/strategies/agnostic/point_in_poly_winding.hpp | 41 ++-
   trunk/boost/geometry/strategies/concepts/distance_concept.hpp | 75 ------
   trunk/boost/geometry/strategies/concepts/within_concept.hpp | 255 ++++++++++++++++++++++--
   trunk/boost/geometry/strategies/strategies.hpp | 3
   trunk/boost/geometry/strategies/within.hpp | 23 +
   9 files changed, 416 insertions(+), 452 deletions(-)

Added: trunk/boost/geometry/algorithms/covered_by.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/geometry/algorithms/covered_by.hpp 2011-07-17 08:26:01 EDT (Sun, 17 Jul 2011)
@@ -0,0 +1,206 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_ALGORITHMS_COVERED_BY_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_COVERED_BY_HPP
+
+
+#include <cstddef>
+
+
+#include <boost/geometry/algorithms/within.hpp>
+
+
+#include <boost/geometry/strategies/cartesian/point_in_box.hpp>
+#include <boost/geometry/strategies/cartesian/box_in_box.hpp>
+
+namespace boost { namespace geometry
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template
+<
+ typename Tag1,
+ typename Tag2,
+ typename Geometry1,
+ typename Geometry2,
+ typename Strategy
+>
+struct covered_by
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPE
+ , (types<Geometry1, Geometry2>)
+ );
+};
+
+
+template <typename Point, typename Box, typename Strategy>
+struct covered_by<point_tag, box_tag, Point, Box, Strategy>
+{
+ static inline bool apply(Point const& point, Box const& box, Strategy const& strategy)
+ {
+ return strategy.apply(point, box);
+ }
+};
+
+template <typename Box1, typename Box2, typename Strategy>
+struct covered_by<box_tag, box_tag, Box1, Box2, Strategy>
+{
+ static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const& strategy)
+ {
+ assert_dimension_equal<Box1, Box2>();
+ return strategy.apply(box1, box2);
+ }
+};
+
+
+
+template <typename Point, typename Ring, typename Strategy>
+struct covered_by<point_tag, ring_tag, Point, Ring, Strategy>
+{
+ static inline bool apply(Point const& point, Ring const& ring, Strategy const& strategy)
+ {
+ return detail::within::point_in_ring
+ <
+ Point,
+ Ring,
+ order_as_direction<geometry::point_order<Ring>::value>::value,
+ geometry::closure<Ring>::value,
+ Strategy
+ >::apply(point, ring) >= 0;
+ }
+};
+
+template <typename Point, typename Polygon, typename Strategy>
+struct covered_by<point_tag, polygon_tag, Point, Polygon, Strategy>
+{
+ static inline bool apply(Point const& point, Polygon const& polygon, Strategy const& strategy)
+ {
+ return detail::within::point_in_polygon
+ <
+ Point,
+ Polygon,
+ order_as_direction<geometry::point_order<Polygon>::value>::value,
+ geometry::closure<Polygon>::value,
+ Strategy
+ >::apply(point, polygon, strategy) >= 0;
+ }
+};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+/*!
+\brief \brief_check12{is inside or on border}
+\ingroup covered_by
+\details \details_check12{covered_by, is inside or on border}.
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\param geometry1 geometry which might be covered_by the second geometry
+\param geometry2 geometry which might contain the first geometry
+\return true if geometry1 is completely contained covered_by geometry2,
+ else false
+\note The default strategy is used for covered_by detection
+
+ */
+template<typename Geometry1, typename Geometry2>
+inline bool covered_by(Geometry1 const& geometry1, Geometry2 const& geometry2)
+{
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2 const>();
+ assert_dimension_equal<Geometry1, Geometry2>();
+
+ typedef typename point_type<Geometry1>::type point_type1;
+ typedef typename point_type<Geometry2>::type point_type2;
+
+ typedef typename strategy::covered_by::services::default_strategy
+ <
+ typename tag<Geometry1>::type,
+ typename tag<Geometry2>::type,
+ typename tag<Geometry1>::type,
+ typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
+ typename tag_cast
+ <
+ typename cs_tag<point_type1>::type, spherical_tag
+ >::type,
+ typename tag_cast
+ <
+ typename cs_tag<point_type2>::type, spherical_tag
+ >::type,
+ Geometry1,
+ Geometry2
+ >::type strategy_type;
+
+ return dispatch::covered_by
+ <
+ typename tag<Geometry1>::type,
+ typename tag<Geometry2>::type,
+ Geometry1,
+ Geometry2,
+ strategy_type
+ >::apply(geometry1, geometry2, strategy_type());
+}
+
+/*!
+\brief \brief_check12{is inside or on border} \brief_strategy
+\ingroup covered_by
+\details \details_check12{covered_by, is inside or on border}, \brief_strategy. \details_strategy_reasons
+\tparam Geometry1 \tparam_geometry
+\tparam Geometry2 \tparam_geometry
+\param geometry1 \param_geometry
+\param geometry2 \param_geometry
+\param geometry1 \param_geometry geometry which might be covered_by the second geometry
+\param geometry2 \param_geometry which might contain the first geometry
+\param strategy strategy to be used
+\return true if geometry1 is completely contained covered_by geometry2,
+ else false
+
+\qbk{distinguish,with strategy}
+
+*/
+template<typename Geometry1, typename Geometry2, typename Strategy>
+inline bool covered_by(Geometry1 const& geometry1, Geometry2 const& geometry2,
+ Strategy const& strategy)
+{
+ concept::within::check
+ <
+ typename tag<Geometry1>::type,
+ typename tag<Geometry2>::type,
+ typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
+ Strategy
+ >();
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2 const>();
+ assert_dimension_equal<Geometry1, Geometry2>();
+
+ return dispatch::covered_by
+ <
+ typename tag<Geometry1>::type,
+ typename tag<Geometry2>::type,
+ Geometry1,
+ Geometry2,
+ Strategy
+ >::apply(geometry1, geometry2, strategy);
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_ALGORITHMS_COVERED_BY_HPP

Modified: trunk/boost/geometry/algorithms/within.hpp
==============================================================================
--- trunk/boost/geometry/algorithms/within.hpp (original)
+++ trunk/boost/geometry/algorithms/within.hpp 2011-07-17 08:26:01 EDT (Sun, 17 Jul 2011)
@@ -31,6 +31,7 @@
 #include <boost/geometry/core/point_order.hpp>
 #include <boost/geometry/core/ring_type.hpp>
 #include <boost/geometry/core/interior_rings.hpp>
+#include <boost/geometry/core/tags.hpp>
 
 #include <boost/geometry/geometries/concepts/check.hpp>
 #include <boost/geometry/strategies/within.hpp>
@@ -49,201 +50,6 @@
 {
 
 
-struct within_state
-{
- bool outside, inside, on_border;
- inline within_state()
- : outside(false)
- , on_border(false)
- {}
-
- inline int code() const
- {
- // Note the order: 1) outside 2) on_border 3) inside
- // If one dim. is outside, it IS outside, else
- // if one dim is on border, it IS on border,
- // if it only inside if inside=true and the rest is false
- return outside ? -1
- : on_border ? 0
- : 1
- ;
- }
-
-};
-
-/*!
- \brief Implementation for boxes
- \ingroup boolean_relations
- \note Should have strategy for e.g. Wrangel
- */
-template
-<
- typename Point,
- typename Box,
- typename Strategy,
- std::size_t Dimension,
- std::size_t DimensionCount
->
-struct point_in_box_helper
-{
- static inline void apply(Point const& p, Box const& b, Strategy const& s, within_state& state)
- {
- typename geometry::coordinate_type<Point>::type const v
- = get<Dimension>(p);
- typename geometry::coordinate_type<Box>::type const b_min
- = get<min_corner, Dimension>(b);
- typename geometry::coordinate_type<Box>::type const b_max
- = get<max_corner, Dimension>(b);
-
- if (geometry::math::equals(v, b_min)
- || geometry::math::equals(v, b_max))
- {
- state.on_border = true;
- }
- else if (v < b_min || v > b_max)
- {
- state.outside = true;
- return;
- }
-
- point_in_box_helper
- <
- Point,
- Box,
- Strategy,
- Dimension + 1,
- DimensionCount
- >::apply(p, b, s, state);
- }
-};
-
-template
-<
- typename Point,
- typename Box,
- typename Strategy,
- std::size_t DimensionCount
->
-struct point_in_box_helper<Point, Box, Strategy, DimensionCount, DimensionCount>
-{
- static inline void apply(Point const& , Box const& , Strategy const&, within_state& )
- {
- }
-};
-
-template
-<
- typename Point,
- typename Box,
- typename Strategy
->
-struct point_in_box
-{
- static inline int apply(Point const& point, Box const& box, Strategy const& strategy)
- {
- assert_dimension_equal<Point, Box>();
- within_state state;
- point_in_box_helper
- <
- Point, Box, Strategy,
- 0, dimension<Point>::type::value
- >::apply(point, box, strategy, state);
- return state.code();
- }
-};
-
-
-template
-<
- typename Box1,
- typename Box2,
- typename Strategy,
- std::size_t Dimension,
- std::size_t DimensionCount
->
-struct box_in_box_helper
-{
- static inline void apply(Box1 const& b_contained, Box2 const& b_containing,
- Strategy const& strategy, within_state& state)
- {
- assert_dimension_equal<Box1, Box2>();
-
- typename geometry::coordinate_type<Box1>::type const ced_min
- = get<min_corner, Dimension>(b_contained);
- typename geometry::coordinate_type<Box1>::type const ced_max
- = get<max_corner, Dimension>(b_contained);
- typename geometry::coordinate_type<Box2>::type const cing_min
- = get<min_corner, Dimension>(b_containing);
- typename geometry::coordinate_type<Box2>::type const cing_max
- = get<max_corner, Dimension>(b_containing);
-
- if (geometry::math::equals(ced_min, cing_min))
- {
- state.on_border = true;
- }
- else if (ced_min < cing_min)
- {
- state.outside = true;
- return;
- }
-
- if (geometry::math::equals(ced_max, cing_max))
- {
- state.on_border = true;
- }
- else if (ced_max > cing_max)
- {
- state.outside = true;
- return;
- }
-
- box_in_box_helper
- <
- Box1,
- Box2,
- Strategy,
- Dimension + 1,
- DimensionCount
- >::apply(b_contained, b_containing, strategy, state);
- }
-};
-
-template
-<
- typename Box1,
- typename Box2,
- typename Strategy,
- std::size_t DimensionCount
->
-struct box_in_box_helper<Box1, Box2, Strategy, DimensionCount, DimensionCount>
-{
- static inline void apply(Box1 const& , Box2 const& , Strategy const&, within_state&)
- {
- }
-};
-
-template
-<
- typename Box1,
- typename Box2,
- typename Strategy
->
-struct box_in_box
-{
- static inline int apply(Box1 const& box1, Box2 const& box2, Strategy const& strategy)
- {
- assert_dimension_equal<Box1, Box2>();
- within_state state;
- box_in_box_helper
- <
- Box1, Box2, Strategy,
- 0, dimension<Box1>::type::value
- >::apply(box1, box2, strategy, state);
- return state.code();
- }
-};
-
-
 template
 <
     typename Point,
@@ -254,7 +60,7 @@
>
 struct point_in_ring
 {
- BOOST_CONCEPT_ASSERT( (geometry::concept::WithinStrategy<Strategy>) );
+ BOOST_CONCEPT_ASSERT( (geometry::concept::WithinStrategyPolygonal<Strategy>) );
 
     static inline int apply(Point const& point, Ring const& ring,
             Strategy const& strategy)
@@ -294,7 +100,6 @@
 };
 
 
-
 // Polygon: in exterior ring, and if so, not within interior ring(s)
 template
 <
@@ -306,7 +111,7 @@
>
 struct point_in_polygon
 {
- BOOST_CONCEPT_ASSERT( (geometry::concept::WithinStrategy<Strategy>) );
+ BOOST_CONCEPT_ASSERT( (geometry::concept::WithinStrategyPolygonal<Strategy>) );
 
     static inline int apply(Point const& point, Polygon const& poly,
             Strategy const& strategy)
@@ -378,137 +183,60 @@
 
 template <typename Point, typename Box, typename Strategy>
 struct within<point_tag, box_tag, Point, Box, Strategy>
- : detail::within::point_in_box
- <
- Point,
- Box,
- Strategy
- >
-{};
+{
+ static inline bool apply(Point const& point, Box const& box, Strategy const& strategy)
+ {
+ return strategy.apply(point, box);
+ }
+};
 
 template <typename Box1, typename Box2, typename Strategy>
 struct within<box_tag, box_tag, Box1, Box2, Strategy>
- : detail::within::box_in_box
- <
- Box1,
- Box2,
- Strategy
- >
-{};
+{
+ static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const& strategy)
+ {
+ assert_dimension_equal<Box1, Box2>();
+ return strategy.apply(box1, box2);
+ }
+};
 
 
 
 template <typename Point, typename Ring, typename Strategy>
 struct within<point_tag, ring_tag, Point, Ring, Strategy>
- : detail::within::point_in_ring
- <
- Point,
- Ring,
- order_as_direction<geometry::point_order<Ring>::value>::value,
- geometry::closure<Ring>::value,
- Strategy
- >
-{};
+{
+ static inline bool apply(Point const& point, Ring const& ring, Strategy const& strategy)
+ {
+ return detail::within::point_in_ring
+ <
+ Point,
+ Ring,
+ order_as_direction<geometry::point_order<Ring>::value>::value,
+ geometry::closure<Ring>::value,
+ Strategy
+ >::apply(point, ring, strategy) == 1;
+ }
+};
 
 template <typename Point, typename Polygon, typename Strategy>
 struct within<point_tag, polygon_tag, Point, Polygon, Strategy>
- : detail::within::point_in_polygon
- <
- Point,
- Polygon,
- order_as_direction<geometry::point_order<Polygon>::value>::value,
- geometry::closure<Polygon>::value,
- Strategy
- >
-{};
-
-} // namespace dispatch
-#endif // DOXYGEN_NO_DISPATCH
-
-
-#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
-namespace strategy { namespace within
 {
-
-/// Strategy for box-in-box (not used but has to be present for default strategy)
-struct unused_strategy {};
-
-namespace services
-{
-
-// Specialize for box-in-areal (box-in-box). This is meant to do box-in-box
-// but will be catched by box-in-any-areal, which has to change later
-// (we might introduce another tag which is not "areal", derived by poly/ring/
-// multi_poly, but NOT by box, and use that here. E.g. "polygonal")
-// Using cartesian prevents spherical yet from compiling, which is good.
-template <typename Box1, typename Box2>
-struct default_strategy<box_tag, areal_tag, cartesian_tag, cartesian_tag, Box1, Box2>
-{
- typedef unused_strategy type;
+ static inline bool apply(Point const& point, Polygon const& polygon, Strategy const& strategy)
+ {
+ return detail::within::point_in_polygon
+ <
+ Point,
+ Polygon,
+ order_as_direction<geometry::point_order<Polygon>::value>::value,
+ geometry::closure<Polygon>::value,
+ Strategy
+ >::apply(point, polygon, strategy) == 1;
+ }
 };
 
-} // namespace services
-
-}} // namespace strategy::within
-
-#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
-
-
-namespace detail
-{
-
-template<typename Geometry1, typename Geometry2>
-inline int within_code(Geometry1 const& geometry1, Geometry2 const& geometry2)
-{
- concept::check<Geometry1 const>();
- concept::check<Geometry2 const>();
-
- typedef typename point_type<Geometry1>::type point_type1;
- typedef typename point_type<Geometry2>::type point_type2;
-
- typedef typename strategy::within::services::default_strategy
- <
- typename tag<Geometry1>::type,
- typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
- typename cs_tag<point_type1>::type,
- typename cs_tag<point_type2>::type,
- point_type1,
- point_type2
- >::type strategy_type;
-
- return dispatch::within
- <
- typename tag<Geometry1>::type,
- typename tag<Geometry2>::type,
- Geometry1,
- Geometry2,
- strategy_type
- >::apply(geometry1, geometry2, strategy_type());
-}
-
-
-template<typename Geometry1, typename Geometry2, typename Strategy>
-inline int within_code(Geometry1 const& geometry1, Geometry2 const& geometry2,
- Strategy const& strategy)
-{
- // Always assume a point-in-polygon strategy here.
- // Because for point-in-box, it makes no sense to specify one.
- BOOST_CONCEPT_ASSERT( (geometry::concept::WithinStrategy<Strategy>) );
-
- concept::check<Geometry1 const>();
- concept::check<Geometry2 const>();
-
- return dispatch::within
- <
- typename tag<Geometry1>::type,
- typename tag<Geometry2>::type,
- Geometry1,
- Geometry2,
- Strategy
- >::apply(geometry1, geometry2, strategy);
-}
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
 
-}
 
 /*!
 \brief \brief_check12{is completely inside}
@@ -538,7 +266,37 @@
 {
     concept::check<Geometry1 const>();
     concept::check<Geometry2 const>();
- return detail::within_code(geometry1, geometry2) == 1;
+ assert_dimension_equal<Geometry1, Geometry2>();
+
+ typedef typename point_type<Geometry1>::type point_type1;
+ typedef typename point_type<Geometry2>::type point_type2;
+
+ typedef typename strategy::within::services::default_strategy
+ <
+ typename tag<Geometry1>::type,
+ typename tag<Geometry2>::type,
+ typename tag<Geometry1>::type,
+ typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
+ typename tag_cast
+ <
+ typename cs_tag<point_type1>::type, spherical_tag
+ >::type,
+ typename tag_cast
+ <
+ typename cs_tag<point_type2>::type, spherical_tag
+ >::type,
+ Geometry1,
+ Geometry2
+ >::type strategy_type;
+
+ return dispatch::within
+ <
+ typename tag<Geometry1>::type,
+ typename tag<Geometry2>::type,
+ Geometry1,
+ Geometry2,
+ strategy_type
+ >::apply(geometry1, geometry2, strategy_type());
 }
 
 /*!
@@ -573,13 +331,25 @@
 inline bool within(Geometry1 const& geometry1, Geometry2 const& geometry2,
         Strategy const& strategy)
 {
- // Always assume a point-in-polygon strategy here.
- // Because for point-in-box, it makes no sense to specify one.
- BOOST_CONCEPT_ASSERT( (geometry::concept::WithinStrategy<Strategy>) );
-
+ concept::within::check
+ <
+ typename tag<Geometry1>::type,
+ typename tag<Geometry2>::type,
+ typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
+ Strategy
+ >();
     concept::check<Geometry1 const>();
     concept::check<Geometry2 const>();
- return detail::within_code(geometry1, geometry2, strategy) == 1;
+ assert_dimension_equal<Geometry1, Geometry2>();
+
+ return dispatch::within
+ <
+ typename tag<Geometry1>::type,
+ typename tag<Geometry2>::type,
+ Geometry1,
+ Geometry2,
+ Strategy
+ >::apply(geometry1, geometry2, strategy);
 }
 
 }} // namespace boost::geometry

Modified: trunk/boost/geometry/core/tags.hpp
==============================================================================
--- trunk/boost/geometry/core/tags.hpp (original)
+++ trunk/boost/geometry/core/tags.hpp 2011-07-17 08:26:01 EDT (Sun, 17 Jul 2011)
@@ -20,18 +20,21 @@
 
 // Tags defining strategies linked to coordinate systems
 
+/// Tag used for casting spherical/geographic coordinate systems
+struct spherical_tag {};
+
 
 /// Tag indicating Cartesian coordinate system family (cartesian,epsg)
 struct cartesian_tag {};
 
 /// Tag indicating Spherical polar coordinate system family
-struct spherical_polar_tag {};
+struct spherical_polar_tag : spherical_tag {};
 
 /// Tag indicating Spherical equatorial coordinate system family
-struct spherical_equatorial_tag {};
+struct spherical_equatorial_tag : spherical_tag {};
 
 /// Tag indicating Geographic coordinate system family (geographic)
-struct geographic_tag {};
+struct geographic_tag : spherical_tag {};
 
 
 
@@ -53,6 +56,9 @@
 /// For areal types (polygon, multi_polygon, box, ring)
 struct areal_tag {};
 
+// Subset of areal types (polygon, multi_polygon, ring)
+struct polygonal_tag : areal_tag {};
+
 /// For volume types (also box (?), polyhedron)
 struct volumetric_tag {};
 
@@ -70,10 +76,10 @@
 struct linestring_tag : single_tag, linear_tag {};
 
 /// OGC Polygon identifying tag
-struct polygon_tag : single_tag, areal_tag {};
+struct polygon_tag : single_tag, polygonal_tag {};
 
 /// Convenience (linear) ring identifying tag
-struct ring_tag : single_tag, areal_tag {};
+struct ring_tag : single_tag, polygonal_tag {};
 
 /// Convenience 2D or 3D box (mbr / aabb) identifying tag
 struct box_tag : single_tag, areal_tag {};

Added: trunk/boost/geometry/multi/algorithms/covered_by.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/geometry/multi/algorithms/covered_by.hpp 2011-07-17 08:26:01 EDT (Sun, 17 Jul 2011)
@@ -0,0 +1,68 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_COVERED_BY_HPP
+#define BOOST_GEOMETRY_MULTI_ALGORITHMS_COVERED_BY_HPP
+
+
+#include <boost/geometry/multi/core/closure.hpp>
+#include <boost/geometry/multi/core/point_order.hpp>
+#include <boost/geometry/multi/core/tags.hpp>
+#include <boost/geometry/multi/algorithms/within.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename Point, typename MultiPolygon, typename Strategy>
+struct covered_by<point_tag, multi_polygon_tag, Point, MultiPolygon, Strategy>
+{
+ static inline bool apply(Point const& point,
+ MultiPolygon const& multi_polygon, Strategy const& strategy)
+ {
+ return detail::within::geometry_multi_within_code
+ <
+ Point,
+ MultiPolygon,
+ Strategy,
+ detail::within::point_in_polygon
+ <
+ Point,
+ typename boost::range_value<MultiPolygon>::type,
+ order_as_direction
+ <
+ geometry::point_order<MultiPolygon>::value
+ >::value,
+ geometry::closure<MultiPolygon>::value,
+ Strategy
+ >
+ >::apply(point, multi_polygon, strategy) >= 0;
+ }
+};
+
+
+} // namespace dispatch
+
+
+#endif // DOXYGEN_NO_DISPATCH
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_COVERED_BY_HPP

Modified: trunk/boost/geometry/multi/algorithms/within.hpp
==============================================================================
--- trunk/boost/geometry/multi/algorithms/within.hpp (original)
+++ trunk/boost/geometry/multi/algorithms/within.hpp 2011-07-17 08:26:01 EDT (Sun, 17 Jul 2011)
@@ -37,7 +37,7 @@
     typename Strategy,
     typename Policy
>
-struct geometry_in_multi
+struct geometry_multi_within_code
 {
     static inline int apply(Geometry const& geometry,
             MultiGeometry const& multi,
@@ -48,7 +48,8 @@
             it != boost::end(multi);
             ++it)
         {
- // Geometry within a multi: true if within one of them
+ // Geometry coding on multi: 1 (within) if within one of them;
+ // 0 (touch) if on border of one of them
             int const code = Policy::apply(geometry, *it, strategy);
             if (code != -1)
             {
@@ -70,21 +71,29 @@
 
 template <typename Point, typename MultiPolygon, typename Strategy>
 struct within<point_tag, multi_polygon_tag, Point, MultiPolygon, Strategy>
- : detail::within::geometry_in_multi
- <
- Point,
- MultiPolygon,
- Strategy,
- detail::within::point_in_polygon
- <
- Point,
- typename boost::range_value<MultiPolygon>::type,
- order_as_direction<geometry::point_order<MultiPolygon>::value>::value,
- geometry::closure<MultiPolygon>::value,
- Strategy
- >
- >
-{};
+{
+ static inline bool apply(Point const& point,
+ MultiPolygon const& multi_polygon, Strategy const& strategy)
+ {
+ return detail::within::geometry_multi_within_code
+ <
+ Point,
+ MultiPolygon,
+ Strategy,
+ detail::within::point_in_polygon
+ <
+ Point,
+ typename boost::range_value<MultiPolygon>::type,
+ order_as_direction
+ <
+ geometry::point_order<MultiPolygon>::value
+ >::value,
+ geometry::closure<MultiPolygon>::value,
+ Strategy
+ >
+ >::apply(point, multi_polygon, strategy) == 1;
+ }
+};
 
 } // namespace dispatch
 #endif // DOXYGEN_NO_DISPATCH

Modified: trunk/boost/geometry/multi/core/tags.hpp
==============================================================================
--- trunk/boost/geometry/multi/core/tags.hpp (original)
+++ trunk/boost/geometry/multi/core/tags.hpp 2011-07-17 08:26:01 EDT (Sun, 17 Jul 2011)
@@ -27,7 +27,7 @@
 struct multi_linestring_tag : multi_tag, linear_tag {};
 
 /// OGC Multi polygon identifying tag
-struct multi_polygon_tag : multi_tag, areal_tag {};
+struct multi_polygon_tag : multi_tag, polygonal_tag {};
 
 /// OGC Geometry Collection identifying tag
 struct geometry_collection_tag : multi_tag {};

Added: trunk/boost/geometry/strategies/agnostic/point_in_box_by_side.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/geometry/strategies/agnostic/point_in_box_by_side.hpp 2011-07-17 08:26:01 EDT (Sun, 17 Jul 2011)
@@ -0,0 +1,151 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_AGNOSTIC_POINT_IN_BOX_BY_SIDE_HPP
+#define BOOST_GEOMETRY_STRATEGIES_AGNOSTIC_POINT_IN_BOX_BY_SIDE_HPP
+
+#include <boost/array.hpp>
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/strategies/covered_by.hpp>
+#include <boost/geometry/strategies/within.hpp>
+
+
+namespace boost { namespace geometry { namespace strategy
+{
+
+namespace within
+{
+
+struct decide_within
+{
+ static inline bool apply(int side, bool& result)
+ {
+ if (side != 1)
+ {
+ result = false;
+ return false;
+ }
+ return true; // continue
+ }
+};
+
+struct decide_covered_by
+{
+ static inline bool apply(int side, bool& result)
+ {
+ if (side != 1)
+ {
+ result = side >= 0;
+ return false;
+ }
+ return true; // continue
+ }
+};
+
+
+template <typename Point, typename Box, typename Decide = decide_within>
+struct point_in_box_by_side
+{
+ typedef typename strategy::side::services::default_strategy
+ <
+ typename cs_tag<Box>::type
+ >::type side_strategy_type;
+
+ static inline bool apply(Point const& point, Box const& box)
+ {
+ // Create (counterclockwise) array of points, the fifth one closes it
+ // Every point should be on the LEFT side (=1), or ON the border (=0),
+ // So >= 1 or >= 0
+ boost::array<typename point_type<Box>::type, 5> bp;
+ geometry::detail::assign_box_corners_oriented<true>(box, bp);
+ bp[4] = bp[0];
+
+ bool result = true;
+ side_strategy_type strategy;
+ boost::ignore_unused_variable_warning(strategy);
+
+ for (int i = 1; i < 5; i++)
+ {
+ int const side = strategy.apply(point, bp[i - 1], bp[i]);
+ if (! Decide::apply(side, result))
+ {
+ return result;
+ }
+ }
+
+ return result;
+ }
+};
+
+
+} // namespace within
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+namespace within { namespace services
+{
+
+template <typename Point, typename Box>
+struct default_strategy
+ <
+ point_tag, box_tag,
+ point_tag, areal_tag,
+ spherical_tag, spherical_tag,
+ Point, Box
+ >
+{
+ typedef within::point_in_box_by_side
+ <
+ Point, Box, within::decide_within
+ > type;
+};
+
+
+
+}} // namespace within::services
+
+
+namespace covered_by { namespace services
+{
+
+
+template <typename Point, typename Box>
+struct default_strategy
+ <
+ point_tag, box_tag,
+ point_tag, areal_tag,
+ spherical_tag, spherical_tag,
+ Point, Box
+ >
+{
+ typedef within::point_in_box_by_side
+ <
+ Point, Box, within::decide_covered_by
+ > type;
+};
+
+
+}} // namespace covered_by::services
+
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}}} // namespace boost::geometry::strategy
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_AGNOSTIC_POINT_IN_BOX_BY_SIDE_HPP

Modified: trunk/boost/geometry/strategies/agnostic/point_in_poly_winding.hpp
==============================================================================
--- trunk/boost/geometry/strategies/agnostic/point_in_poly_winding.hpp (original)
+++ trunk/boost/geometry/strategies/agnostic/point_in_poly_winding.hpp 2011-07-17 08:26:01 EDT (Sun, 17 Jul 2011)
@@ -17,6 +17,7 @@
 #include <boost/geometry/util/select_calculation_type.hpp>
 
 #include <boost/geometry/strategies/side.hpp>
+#include <boost/geometry/strategies/covered_by.hpp>
 #include <boost/geometry/strategies/within.hpp>
 
 
@@ -181,23 +182,18 @@
 {
 
 // Register using "areal_tag" for ring, polygon, multi-polygon
-template <typename Point, typename PointOfSegment>
-struct default_strategy<point_tag, areal_tag, cartesian_tag, cartesian_tag, Point, PointOfSegment>
+template <typename AnyTag, typename Point, typename Geometry>
+struct default_strategy<point_tag, AnyTag, point_tag, areal_tag, cartesian_tag, cartesian_tag, Point, Geometry>
 {
- typedef winding<Point, PointOfSegment> type;
+ typedef winding<Point, typename geometry::point_type<Geometry>::type> type;
 };
 
-template <typename Point, typename PointOfSegment>
-struct default_strategy<point_tag, areal_tag, spherical_polar_tag, spherical_polar_tag, Point, PointOfSegment>
+template <typename AnyTag, typename Point, typename Geometry>
+struct default_strategy<point_tag, AnyTag, point_tag, areal_tag, spherical_tag, spherical_tag, Point, Geometry>
 {
- typedef winding<Point, PointOfSegment> type;
+ typedef winding<Point, typename geometry::point_type<Geometry>::type> type;
 };
 
-template <typename Point, typename PointOfSegment>
-struct default_strategy<point_tag, areal_tag, spherical_equatorial_tag, spherical_equatorial_tag, Point, PointOfSegment>
-{
- typedef winding<Point, PointOfSegment> type;
-};
 
 } // namespace services
 
@@ -207,6 +203,29 @@
 }} // namespace strategy::within
 
 
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+namespace strategy { namespace covered_by { namespace services
+{
+
+// Register using "areal_tag" for ring, polygon, multi-polygon
+template <typename AnyTag, typename Point, typename Geometry>
+struct default_strategy<point_tag, AnyTag, point_tag, areal_tag, cartesian_tag, cartesian_tag, Point, Geometry>
+{
+ typedef strategy::within::winding<Point, typename geometry::point_type<Geometry>::type> type;
+};
+
+template <typename AnyTag, typename Point, typename Geometry>
+struct default_strategy<point_tag, AnyTag, point_tag, areal_tag, spherical_tag, spherical_tag, Point, Geometry>
+{
+ typedef strategy::within::winding<Point, typename geometry::point_type<Geometry>::type> type;
+};
+
+
+}}} // namespace strategy::covered_by::services
+#endif
+
+
 }} // namespace boost::geometry
 
 

Added: trunk/boost/geometry/strategies/cartesian/box_in_box.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/geometry/strategies/cartesian/box_in_box.hpp 2011-07-17 08:26:01 EDT (Sun, 17 Jul 2011)
@@ -0,0 +1,176 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BOX_IN_BOX_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BOX_IN_BOX_HPP
+
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/strategies/covered_by.hpp>
+#include <boost/geometry/strategies/within.hpp>
+
+
+namespace boost { namespace geometry { namespace strategy
+{
+
+
+namespace within
+{
+
+struct box_within_range
+{
+ template <typename BoxContainedValue, typename BoxContainingValue>
+ static inline bool apply(BoxContainedValue const& bed_min
+ , BoxContainedValue const& bed_max
+ , BoxContainingValue const& bing_min
+ , BoxContainingValue const& bing_max)
+ {
+ return bed_min > bing_min && bed_max < bing_max;
+ }
+};
+
+
+struct box_covered_by_range
+{
+ template <typename BoxContainedValue, typename BoxContainingValue>
+ static inline bool apply(BoxContainedValue const& bed_min
+ , BoxContainedValue const& bed_max
+ , BoxContainingValue const& bing_min
+ , BoxContainingValue const& bing_max)
+ {
+ return bed_min >= bing_min && bed_max <= bing_max;
+ }
+};
+
+
+template
+<
+ typename SubStrategy,
+ typename Box1,
+ typename Box2,
+ std::size_t Dimension,
+ std::size_t DimensionCount
+>
+struct relate_box_box_loop
+{
+ static inline bool apply(Box1 const& b_contained, Box2 const& b_containing)
+ {
+ assert_dimension_equal<Box1, Box2>();
+
+ if (! SubStrategy::apply(
+ get<min_corner, Dimension>(b_contained),
+ get<max_corner, Dimension>(b_contained),
+ get<min_corner, Dimension>(b_containing),
+ get<max_corner, Dimension>(b_containing)
+ )
+ )
+ {
+ return false;
+ }
+
+ return relate_box_box_loop
+ <
+ SubStrategy,
+ Box1, Box2,
+ Dimension + 1, DimensionCount
+ >::apply(b_contained, b_containing);
+ }
+};
+
+template
+<
+ typename SubStrategy,
+ typename Box1,
+ typename Box2,
+ std::size_t DimensionCount
+>
+struct relate_box_box_loop<SubStrategy, Box1, Box2, DimensionCount, DimensionCount>
+{
+ static inline bool apply(Box1 const& , Box2 const& )
+ {
+ return true;
+ }
+};
+
+template
+<
+ typename Box1,
+ typename Box2,
+ typename SubStrategy = box_within_range
+>
+struct box_in_box
+{
+ static inline bool apply(Box1 const& box1, Box2 const& box2)
+ {
+ return relate_box_box_loop
+ <
+ SubStrategy,
+ Box1, Box2, 0, dimension<Box1>::type::value
+ >::apply(box1, box2);
+ }
+};
+
+
+} // namespace within
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+namespace within { namespace services
+{
+
+template <typename BoxContained, typename BoxContaining>
+struct default_strategy
+ <
+ box_tag, box_tag,
+ box_tag, areal_tag,
+ cartesian_tag, cartesian_tag,
+ BoxContained, BoxContaining
+ >
+{
+ typedef within::box_in_box<BoxContained, BoxContaining> type;
+};
+
+
+}} // namespace within::services
+
+namespace covered_by { namespace services
+{
+
+template <typename BoxContained, typename BoxContaining>
+struct default_strategy
+ <
+ box_tag, box_tag,
+ box_tag, areal_tag,
+ cartesian_tag, cartesian_tag,
+ BoxContained, BoxContaining
+ >
+{
+ typedef within::box_in_box
+ <
+ BoxContained, BoxContaining,
+ within::box_covered_by_range
+ > type;
+};
+
+}} // namespace covered_by::services
+
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}}} // namespace boost::geometry::strategy
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BOX_IN_BOX_HPP

Added: trunk/boost/geometry/strategies/cartesian/point_in_box.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/geometry/strategies/cartesian/point_in_box.hpp 2011-07-17 08:26:01 EDT (Sun, 17 Jul 2011)
@@ -0,0 +1,172 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_BOX_HPP
+#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_BOX_HPP
+
+
+#include <boost/geometry/core/access.hpp>
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/strategies/covered_by.hpp>
+#include <boost/geometry/strategies/within.hpp>
+
+
+namespace boost { namespace geometry { namespace strategy
+{
+
+namespace within
+{
+
+
+struct within_range
+{
+ template <typename Value1, typename Value2>
+ static inline bool apply(Value1 const& value, Value2 const& min_value, Value2 const& max_value)
+ {
+ return value > min_value && value < max_value;
+ }
+};
+
+
+struct covered_by_range
+{
+ template <typename Value1, typename Value2>
+ static inline bool apply(Value1 const& value, Value2 const& min_value, Value2 const& max_value)
+ {
+ return value >= min_value && value <= max_value;
+ }
+};
+
+
+template
+<
+ typename SubStrategy,
+ typename Point,
+ typename Box,
+ std::size_t Dimension,
+ std::size_t DimensionCount
+>
+struct relate_point_box_loop
+{
+ static inline bool apply(Point const& point, Box const& box)
+ {
+ if (! SubStrategy::apply(get<Dimension>(point),
+ get<min_corner, Dimension>(box),
+ get<max_corner, Dimension>(box))
+ )
+ {
+ return false;
+ }
+
+ return relate_point_box_loop
+ <
+ SubStrategy,
+ Point, Box,
+ Dimension + 1, DimensionCount
+ >::apply(point, box);
+ }
+};
+
+
+template
+<
+ typename SubStrategy,
+ typename Point,
+ typename Box,
+ std::size_t DimensionCount
+>
+struct relate_point_box_loop<SubStrategy, Point, Box, DimensionCount, DimensionCount>
+{
+ static inline bool apply(Point const& , Box const& )
+ {
+ return true;
+ }
+};
+
+
+template
+<
+ typename Point,
+ typename Box,
+ typename SubStrategy = within_range
+>
+struct point_in_box
+{
+ static inline bool apply(Point const& point, Box const& box)
+ {
+ return relate_point_box_loop
+ <
+ SubStrategy,
+ Point, Box,
+ 0, dimension<Point>::type::value
+ >::apply(point, box);
+ }
+};
+
+
+} // namespace within
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+namespace within { namespace services
+{
+
+template <typename Point, typename Box>
+struct default_strategy
+ <
+ point_tag, box_tag,
+ point_tag, areal_tag,
+ cartesian_tag, cartesian_tag,
+ Point, Box
+ >
+{
+ typedef within::point_in_box<Point, Box> type;
+};
+
+
+}} // namespace within::services
+
+
+namespace covered_by { namespace services
+{
+
+
+template <typename Point, typename Box>
+struct default_strategy
+ <
+ point_tag, box_tag,
+ point_tag, areal_tag,
+ cartesian_tag, cartesian_tag,
+ Point, Box
+ >
+{
+ typedef within::point_in_box
+ <
+ Point, Box,
+ within::covered_by_range
+ > type;
+};
+
+
+}} // namespace covered_by::services
+
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}}} // namespace boost::geometry::strategy
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_BOX_HPP

Modified: trunk/boost/geometry/strategies/concepts/distance_concept.hpp
==============================================================================
--- trunk/boost/geometry/strategies/concepts/distance_concept.hpp (original)
+++ trunk/boost/geometry/strategies/concepts/distance_concept.hpp 2011-07-17 08:26:01 EDT (Sun, 17 Jul 2011)
@@ -19,13 +19,7 @@
 
 #include <boost/concept_check.hpp>
 
-#include <boost/function_types/function_arity.hpp>
-#include <boost/function_types/is_member_function_pointer.hpp>
-#include <boost/function_types/parameter_types.hpp>
-#include <boost/mpl/at.hpp>
-#include <boost/mpl/int.hpp>
-#include <boost/mpl/plus.hpp>
-#include <boost/type_traits.hpp>
+#include <boost/geometry/util/parameter_type_of.hpp>
 
 #include <boost/geometry/geometries/concepts/point_concept.hpp>
 #include <boost/geometry/geometries/segment.hpp>
@@ -50,40 +44,15 @@
         template <typename ApplyMethod>
         static void apply(ApplyMethod const&)
         {
- namespace ft = boost::function_types;
- typedef typename ft::parameter_types
- <
- ApplyMethod
- >::type parameter_types;
-
- typedef typename boost::mpl::if_
- <
- ft::is_member_function_pointer<ApplyMethod>,
- boost::mpl::int_<1>,
- boost::mpl::int_<0>
- >::type base_index;
-
             // 1: inspect and define both arguments of apply
- typedef typename boost::remove_reference
+ typedef typename parameter_type_of
                 <
- typename boost::mpl::at
- <
- parameter_types,
- base_index
- >::type
+ ApplyMethod, 0
>::type ptype1;
 
- typedef typename boost::remove_reference
+ typedef typename parameter_type_of
                 <
- typename boost::mpl::at
- <
- parameter_types,
- typename boost::mpl::plus
- <
- base_index,
- boost::mpl::int_<1>
- >::type
- >::type
+ ApplyMethod, 1
>::type ptype2;
 
             // 2) check if apply-arguments fulfill point concept
@@ -177,40 +146,14 @@
         template <typename ApplyMethod>
         static void apply(ApplyMethod const&)
         {
- namespace ft = boost::function_types;
- typedef typename ft::parameter_types
- <
- ApplyMethod
- >::type parameter_types;
-
- typedef typename boost::mpl::if_
- <
- ft::is_member_function_pointer<ApplyMethod>,
- boost::mpl::int_<1>,
- boost::mpl::int_<0>
- >::type base_index;
-
- // 1: inspect and define both arguments of apply
- typedef typename boost::remove_reference
+ typedef typename parameter_type_of
                 <
- typename boost::mpl::at
- <
- parameter_types,
- base_index
- >::type
+ ApplyMethod, 0
>::type ptype;
 
- typedef typename boost::remove_reference
+ typedef typename parameter_type_of
                 <
- typename boost::mpl::at
- <
- parameter_types,
- typename boost::mpl::plus
- <
- base_index,
- boost::mpl::int_<1>
- >::type
- >::type
+ ApplyMethod, 1
>::type sptype;
 
             // 2) check if apply-arguments fulfill point concept

Modified: trunk/boost/geometry/strategies/concepts/within_concept.hpp
==============================================================================
--- trunk/boost/geometry/strategies/concepts/within_concept.hpp (original)
+++ trunk/boost/geometry/strategies/concepts/within_concept.hpp 2011-07-17 08:26:01 EDT (Sun, 17 Jul 2011)
@@ -17,6 +17,9 @@
 
 
 #include <boost/concept_check.hpp>
+#include <boost/function_types/result_type.hpp>
+
+#include <boost/geometry/util/parameter_type_of.hpp>
 
 
 namespace boost { namespace geometry { namespace concept
@@ -24,57 +27,265 @@
 
 
 /*!
- \brief Checks strategy for within (point-in-polygon)
- \ingroup within
+\brief Checks strategy for within (point-in-polygon)
+\ingroup within
 */
 template <typename Strategy>
-class WithinStrategy
+class WithinStrategyPolygonal
 {
 #ifndef DOXYGEN_NO_CONCEPT_MEMBERS
 
- // 1) must define state_type,
+ // 1) must define state_type
     typedef typename Strategy::state_type state_type;
 
- // 2) must define point_type (of "point" in poly)
- typedef typename Strategy::point_type point_type;
+ struct checker
+ {
+ template <typename ApplyMethod, typename ResultMethod>
+ static void apply(ApplyMethod const&, ResultMethod const& )
+ {
+ typedef typename parameter_type_of
+ <
+ ApplyMethod, 0
+ >::type point_type;
+ typedef typename parameter_type_of
+ <
+ ApplyMethod, 1
+ >::type segment_point_type;
+
+ // CHECK: apply-arguments should both fulfill point concept
+ BOOST_CONCEPT_ASSERT
+ (
+ (concept::ConstPoint<point_type>)
+ );
+
+ BOOST_CONCEPT_ASSERT
+ (
+ (concept::ConstPoint<segment_point_type>)
+ );
+
+ // CHECK: return types (result: int, apply: bool)
+ BOOST_MPL_ASSERT_MSG
+ (
+ (boost::is_same
+ <
+ bool, typename boost::function_types::result_type<ApplyMethod>::type
+ >::type::value),
+ WRONG_RETURN_TYPE_OF_APPLY
+ , (bool)
+ );
+ BOOST_MPL_ASSERT_MSG
+ (
+ (boost::is_same
+ <
+ int, typename boost::function_types::result_type<ResultMethod>::type
+ >::type::value),
+ WRONG_RETURN_TYPE_OF_RESULT
+ , (int)
+ );
+
+
+ // CHECK: calling method apply and result
+ Strategy const* str;
+ state_type* st;
+ point_type const* p;
+ segment_point_type const* sp;
+
+ bool b = str->apply(*p, *sp, *sp, *st);
+ int r = str->result(*st);
 
- // 3) must define point_type, of polygon (segments)
- typedef typename Strategy::segment_point_type spoint_type;
+ boost::ignore_unused_variable_warning(r);
+ boost::ignore_unused_variable_warning(b);
+ boost::ignore_unused_variable_warning(str);
+ }
+ };
+
+
+public :
+ BOOST_CONCEPT_USAGE(WithinStrategyPolygonal)
+ {
+ checker::apply(&Strategy::apply, &Strategy::result);
+ }
+#endif
+};
 
+template <typename Strategy>
+class WithinStrategyPointBox
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
 
- struct check_methods
+ struct checker
     {
- static void apply()
+ template <typename ApplyMethod>
+ static void apply(ApplyMethod const&)
         {
- Strategy const* str;
+ typedef typename parameter_type_of
+ <
+ ApplyMethod, 0
+ >::type point_type;
+ typedef typename parameter_type_of
+ <
+ ApplyMethod, 1
+ >::type box_type;
+
+ // CHECK: apply-arguments should fulfill point/box concept
+ BOOST_CONCEPT_ASSERT
+ (
+ (concept::ConstPoint<point_type>)
+ );
+
+ BOOST_CONCEPT_ASSERT
+ (
+ (concept::ConstBox<box_type>)
+ );
+
+ // CHECK: return types (apply: bool)
+ BOOST_MPL_ASSERT_MSG
+ (
+ (boost::is_same
+ <
+ bool,
+ typename boost::function_types::result_type<ApplyMethod>::type
+ >::type::value),
+ WRONG_RETURN_TYPE
+ , (bool)
+ );
 
- state_type* st;
+
+ // CHECK: calling method apply
+ Strategy const* str;
             point_type const* p;
- spoint_type const* sp;
+ box_type const* bx;
 
- // 4) must implement a method apply
- // having a point, two segment-points, and state
- str->apply(*p, *sp, *sp, *st);
+ bool b = str->apply(*p, *bx);
 
- // 5) must implement a method result returning int
- int r = str->result(*st);
+ boost::ignore_unused_variable_warning(b);
+ boost::ignore_unused_variable_warning(str);
+ }
+ };
 
- boost::ignore_unused_variable_warning(r);
+
+public :
+ BOOST_CONCEPT_USAGE(WithinStrategyPointBox)
+ {
+ checker::apply(&Strategy::apply);
+ }
+#endif
+};
+
+template <typename Strategy>
+class WithinStrategyBoxBox
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+
+ struct checker
+ {
+ template <typename ApplyMethod>
+ static void apply(ApplyMethod const&)
+ {
+ typedef typename parameter_type_of
+ <
+ ApplyMethod, 0
+ >::type box_type1;
+ typedef typename parameter_type_of
+ <
+ ApplyMethod, 1
+ >::type box_type2;
+
+ // CHECK: apply-arguments should both fulfill box concept
+ BOOST_CONCEPT_ASSERT
+ (
+ (concept::ConstBox<box_type1>)
+ );
+
+ BOOST_CONCEPT_ASSERT
+ (
+ (concept::ConstBox<box_type2>)
+ );
+
+ // CHECK: return types (apply: bool)
+ BOOST_MPL_ASSERT_MSG
+ (
+ (boost::is_same
+ <
+ bool,
+ typename boost::function_types::result_type<ApplyMethod>::type
+ >::type::value),
+ WRONG_RETURN_TYPE
+ , (bool)
+ );
+
+
+ // CHECK: calling method apply
+ Strategy const* str;
+ box_type1 const* b1;
+ box_type2 const* b2;
+
+ bool b = str->apply(*b1, *b2);
+
+ boost::ignore_unused_variable_warning(b);
             boost::ignore_unused_variable_warning(str);
         }
     };
 
 
 public :
- BOOST_CONCEPT_USAGE(WithinStrategy)
+ BOOST_CONCEPT_USAGE(WithinStrategyBoxBox)
     {
- check_methods::apply();
+ checker::apply(&Strategy::apply);
     }
 #endif
 };
 
+// So now: boost::geometry::concept::within
+namespace within
+{
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch
+{
+
+template <typename FirstTag, typename SecondTag, typename CastedTag, typename Strategy>
+struct check_within
+{};
+
+
+template <typename AnyTag, typename Strategy>
+struct check_within<point_tag, AnyTag, areal_tag, Strategy>
+{
+ BOOST_CONCEPT_ASSERT( (WithinStrategyPolygonal<Strategy>) );
+};
+
+
+template <typename Strategy>
+struct check_within<point_tag, box_tag, areal_tag, Strategy>
+{
+ BOOST_CONCEPT_ASSERT( (WithinStrategyPointBox<Strategy>) );
+};
+
+template <typename Strategy>
+struct check_within<box_tag, box_tag, areal_tag, Strategy>
+{
+ BOOST_CONCEPT_ASSERT( (WithinStrategyBoxBox<Strategy>) );
+};
+
+
+} // namespace dispatch
+#endif
+
+
+/*!
+\brief Checks, in compile-time, the concept of any within-strategy
+\ingroup concepts
+*/
+template <typename FirstTag, typename SecondTag, typename CastedTag, typename Strategy>
+inline void check()
+{
+ dispatch::check_within<FirstTag, SecondTag, CastedTag, Strategy> c;
+ boost::ignore_unused_variable_warning(c);
+}
+
 
+}}}} // namespace boost::geometry::concept::within
 
-}}} // namespace boost::geometry::concept
 
 #endif // BOOST_GEOMETRY_STRATEGIES_CONCEPTS_WITHIN_CONCEPT_HPP

Added: trunk/boost/geometry/strategies/covered_by.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/geometry/strategies/covered_by.hpp 2011-07-17 08:26:01 EDT (Sun, 17 Jul 2011)
@@ -0,0 +1,72 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_COVERED_BY_HPP
+#define BOOST_GEOMETRY_STRATEGIES_COVERED_BY_HPP
+
+#include <boost/mpl/assert.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+namespace strategy { namespace covered_by
+{
+
+
+namespace services
+{
+
+/*!
+\brief Traits class binding a covered_by determination strategy to a coordinate system
+\ingroup covered_by
+\tparam TagContained tag (possibly casted) of point-type
+\tparam TagContained tag (possibly casted) of (possibly) containing type
+\tparam CsTagContained tag of coordinate system of point-type
+\tparam CsTagContaining tag of coordinate system of (possibly) containing type
+\tparam Geometry geometry-type of input (often point, or box)
+\tparam GeometryContaining geometry-type of input (possibly) containing type
+*/
+template
+<
+ typename TagContained,
+ typename TagContaining,
+ typename CastedTagContained,
+ typename CastedTagContaining,
+ typename CsTagContained,
+ typename CsTagContaining,
+ typename GeometryContained,
+ typename GeometryContaining
+>
+struct default_strategy
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_IMPLEMENTED_FOR_THIS_TYPES
+ , (types<GeometryContained, GeometryContaining>)
+ );
+};
+
+
+} // namespace services
+
+
+}} // namespace strategy::covered_by
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_COVERED_BY_HPP
+

Modified: trunk/boost/geometry/strategies/strategies.hpp
==============================================================================
--- trunk/boost/geometry/strategies/strategies.hpp (original)
+++ trunk/boost/geometry/strategies/strategies.hpp 2011-07-17 08:26:01 EDT (Sun, 17 Jul 2011)
@@ -28,10 +28,12 @@
 #include <boost/geometry/strategies/within.hpp>
 
 #include <boost/geometry/strategies/cartesian/area_surveyor.hpp>
+#include <boost/geometry/strategies/cartesian/box_in_box.hpp>
 #include <boost/geometry/strategies/cartesian/centroid_bashein_detmer.hpp>
 #include <boost/geometry/strategies/cartesian/centroid_weighted_length.hpp>
 #include <boost/geometry/strategies/cartesian/distance_pythagoras.hpp>
 #include <boost/geometry/strategies/cartesian/distance_projected_point.hpp>
+#include <boost/geometry/strategies/cartesian/point_in_box.hpp>
 #include <boost/geometry/strategies/cartesian/point_in_poly_franklin.hpp>
 #include <boost/geometry/strategies/cartesian/point_in_poly_crossings_multiply.hpp>
 #include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
@@ -43,6 +45,7 @@
 #include <boost/geometry/strategies/spherical/ssf.hpp>
 
 #include <boost/geometry/strategies/agnostic/hull_graham_andrew.hpp>
+#include <boost/geometry/strategies/agnostic/point_in_box_by_side.hpp>
 #include <boost/geometry/strategies/agnostic/point_in_poly_winding.hpp>
 #include <boost/geometry/strategies/agnostic/simplify_douglas_peucker.hpp>
 

Modified: trunk/boost/geometry/strategies/within.hpp
==============================================================================
--- trunk/boost/geometry/strategies/within.hpp (original)
+++ trunk/boost/geometry/strategies/within.hpp 2011-07-17 08:26:01 EDT (Sun, 17 Jul 2011)
@@ -16,7 +16,6 @@
 
 #include <boost/mpl/assert.hpp>
 
-#include <boost/geometry/strategies/tags.hpp>
 
 namespace boost { namespace geometry
 {
@@ -29,28 +28,32 @@
 {
 
 /*!
- \brief Traits class binding a within determination strategy to a coordinate system
- \ingroup within
- \tparam CsTagContained tag of coordinate system of point-type
- \tparam CsTagContained tag of coordinate system of segment-type
- \tparam Point point-type of input points
- \tparam PointContaining point-type of input segment-points
+\brief Traits class binding a within determination strategy to a coordinate system
+\ingroup within
+\tparam TagContained tag (possibly casted) of point-type
+\tparam TagContained tag (possibly casted) of (possibly) containing type
+\tparam CsTagContained tag of coordinate system of point-type
+\tparam CsTagContaining tag of coordinate system of (possibly) containing type
+\tparam Geometry geometry-type of input (often point, or box)
+\tparam GeometryContaining geometry-type of input (possibly) containing type
 */
 template
 <
     typename TagContained,
     typename TagContaining,
+ typename CastedTagContained,
+ typename CastedTagContaining,
     typename CsTagContained,
     typename CsTagContaining,
- typename Point,
- typename PointContaining
+ typename GeometryContained,
+ typename GeometryContaining
>
 struct default_strategy
 {
     BOOST_MPL_ASSERT_MSG
         (
             false, NOT_IMPLEMENTED_FOR_THIS_TYPES
- , (types<Point, PointContaining>)
+ , (types<GeometryContained, GeometryContaining>)
         );
 };
 

Added: trunk/boost/geometry/util/parameter_type_of.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/geometry/util/parameter_type_of.hpp 2011-07-17 08:26:01 EDT (Sun, 17 Jul 2011)
@@ -0,0 +1,75 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_UTIL_PARAMETER_TYPE_OF_HPP
+#define BOOST_GEOMETRY_UTIL_PARAMETER_TYPE_OF_HPP
+
+
+#include <boost/function_types/function_arity.hpp>
+#include <boost/function_types/is_member_function_pointer.hpp>
+#include <boost/function_types/parameter_types.hpp>
+#include <boost/mpl/at.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/plus.hpp>
+#include <boost/type_traits.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+/*!
+\brief Meta-function selecting a parameter type of a (member) function, by index
+\ingroup utility
+ */
+template <typename Method, std::size_t Index>
+struct parameter_type_of
+{
+ typedef typename boost::function_types::parameter_types
+ <
+ Method
+ >::type parameter_types;
+
+ typedef typename boost::mpl::if_
+ <
+ boost::function_types::is_member_function_pointer<Method>,
+ boost::mpl::int_<1>,
+ boost::mpl::int_<0>
+ >::type base_index_type;
+
+ typedef typename boost::mpl::if_c
+ <
+ Index == 0,
+ base_index_type,
+ typename boost::mpl::plus
+ <
+ base_index_type,
+ boost::mpl::int_<Index>
+ >::type
+ >::type indexed_type;
+
+ typedef typename boost::remove_reference
+ <
+ typename boost::mpl::at
+ <
+ parameter_types,
+ indexed_type
+ >::type
+ >::type type;
+};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_UTIL_PARAMETER_TYPE_OF_HPP


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk