Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r63579 - in sandbox/geometry: boost/geometry/algorithms boost/geometry/algorithms/detail/overlay boost/geometry/algorithms/detail/sections boost/geometry/core boost/geometry/extensions/gis/geographic/strategies boost/geometry/multi/algorithms/detail/sections boost/geometry/strategies boost/geometry/strategies/agnostic boost/geometry/strategies/cartesian boost/geometry/strategies/concepts boost/geometry/strategies/spherical boost/geometry/util libs/geometry/example libs/geometry/test libs/geometry/test/algorithms libs/geometry/test/extensions/gis/latlong libs/geometry/test/strategies
From: barend.gehrels_at_[hidden]
Date: 2010-07-04 06:01:14


Author: barendgehrels
Date: 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
New Revision: 63579
URL: http://svn.boost.org/trac/boost/changeset/63579

Log:
Added non-const version of get_section
Major changes in distance strategies
Changed double from simplify to template parameter
Added a promote_floating_point
Added a fp_coordinate_type
Added namespaced point in custom example
Added mpl assertion in overlaps (should be done in most algorithms by default)
Added high precision test for various distance algorithms
Added:
   sandbox/geometry/boost/geometry/util/promote_floating_point.hpp (contents, props changed)
   sandbox/geometry/libs/geometry/test/algorithms/comparable_distance.cpp (contents, props changed)
   sandbox/geometry/libs/geometry/test/algorithms/comparable_distance.vcproj (contents, props changed)
   sandbox/geometry/libs/geometry/test/ttmath.vsprops (contents, props changed)
Text files modified:
   sandbox/geometry/boost/geometry/algorithms/detail/overlay/enrichment_info.hpp | 2
   sandbox/geometry/boost/geometry/algorithms/detail/sections/get_section.hpp | 91 ++++++++---
   sandbox/geometry/boost/geometry/algorithms/distance.hpp | 29 ++-
   sandbox/geometry/boost/geometry/algorithms/overlaps.hpp | 12 +
   sandbox/geometry/boost/geometry/algorithms/simplify.hpp | 42 ++--
   sandbox/geometry/boost/geometry/core/coordinate_type.hpp | 29 ++-
   sandbox/geometry/boost/geometry/core/radian_access.hpp | 10
   sandbox/geometry/boost/geometry/extensions/gis/geographic/strategies/andoyer.hpp | 247 ++++++++++++++++++++-----------
   sandbox/geometry/boost/geometry/extensions/gis/geographic/strategies/vincenty.hpp | 274 ++++++++++++++++++++++-------------
   sandbox/geometry/boost/geometry/multi/algorithms/detail/sections/get_section.hpp | 20 +
   sandbox/geometry/boost/geometry/strategies/agnostic/simplify_douglas_peucker.hpp | 21 +-
   sandbox/geometry/boost/geometry/strategies/cartesian/distance_projected_point.hpp | 188 +++++++++++++++++++++---
   sandbox/geometry/boost/geometry/strategies/cartesian/distance_pythagoras.hpp | 231 ++++++++++++++++++++++++++++-
   sandbox/geometry/boost/geometry/strategies/concepts/distance_concept.hpp | 48 ++++++
   sandbox/geometry/boost/geometry/strategies/distance.hpp | 65 ++++++++
   sandbox/geometry/boost/geometry/strategies/distance_result.hpp | 306 +--------------------------------------
   sandbox/geometry/boost/geometry/strategies/spherical/distance_cross_track.hpp | 146 +++++++++++++++---
   sandbox/geometry/boost/geometry/strategies/spherical/distance_haversine.hpp | 251 +++++++++++++++++++++++++++++---
   sandbox/geometry/libs/geometry/example/c01_custom_point_example.cpp | 22 ++
   sandbox/geometry/libs/geometry/test/algorithms/algorithms_tests.sln | 6
   sandbox/geometry/libs/geometry/test/algorithms/distance.cpp | 54 ++++---
   sandbox/geometry/libs/geometry/test/algorithms/intersection.cpp | 5
   sandbox/geometry/libs/geometry/test/algorithms/overlaps.cpp | 4
   sandbox/geometry/libs/geometry/test/algorithms/simplify.cpp | 2
   sandbox/geometry/libs/geometry/test/algorithms/simplify.vcproj | 9
   sandbox/geometry/libs/geometry/test/extensions/gis/latlong/andoyer.cpp | 9 +
   sandbox/geometry/libs/geometry/test/extensions/gis/latlong/latlong.sln | 6
   sandbox/geometry/libs/geometry/test/strategies/cross_track.cpp | 19 ++
   sandbox/geometry/libs/geometry/test/strategies/cross_track.vcproj | 4
   sandbox/geometry/libs/geometry/test/strategies/haversine.cpp | 200 ++++++++++++++++++++++++-
   sandbox/geometry/libs/geometry/test/strategies/haversine.vcproj | 4
   sandbox/geometry/libs/geometry/test/strategies/projected_point.cpp | 103 +++++++++---
   sandbox/geometry/libs/geometry/test/strategies/projected_point.vcproj | 4
   sandbox/geometry/libs/geometry/test/strategies/pythagoras.cpp | 252 ++++++++++++++++++++++++--------
   sandbox/geometry/libs/geometry/test/strategies/pythagoras.vcproj | 4
   35 files changed, 1912 insertions(+), 807 deletions(-)

Modified: sandbox/geometry/boost/geometry/algorithms/detail/overlay/enrichment_info.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/algorithms/detail/overlay/enrichment_info.hpp (original)
+++ sandbox/geometry/boost/geometry/algorithms/detail/overlay/enrichment_info.hpp 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -36,7 +36,7 @@
         : travels_to_vertex_index(-1)
         , travels_to_ip_index(-1)
         , next_ip_index(-1)
- , distance(geometry::make_distance_result<distance_type>(0))
+ , distance(distance_type())
     {}
 
     // vertex to which is free travel after this IP,

Modified: sandbox/geometry/boost/geometry/algorithms/detail/sections/get_section.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/algorithms/detail/sections/get_section.hpp (original)
+++ sandbox/geometry/boost/geometry/algorithms/detail/sections/get_section.hpp 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -15,10 +15,8 @@
 #include <boost/geometry/core/access.hpp>
 #include <boost/geometry/core/exterior_ring.hpp>
 #include <boost/geometry/core/interior_rings.hpp>
-
 #include <boost/geometry/iterators/range_type.hpp>
-
-#include <boost/geometry/geometries/segment.hpp>
+#include <boost/geometry/util/add_const_if_c.hpp>
 
 
 
@@ -30,15 +28,26 @@
 namespace dispatch
 {
 
-template <typename Tag, typename Geometry, typename Section>
+// Generic case (linestring/linear ring)
+template <typename Tag, typename Geometry, typename Section, bool IsConst>
 struct get_section
 {
+ typedef typename add_const_if_c
+ <
+ IsConst,
+ Geometry
+ >::type geometry_type;
+
     typedef typename boost::range_iterator
         <
- typename geometry::range_type<Geometry>::type const
+ typename add_const_if_c
+ <
+ IsConst,
+ typename geometry::range_type<Geometry>::type
+ >::type
>::type iterator_type;
 
- static inline void apply(Geometry const& geometry, Section const& section,
+ static inline void apply(geometry_type& geometry, Section const& section,
                 iterator_type& begin, iterator_type& end)
     {
         begin = boost::begin(geometry) + section.begin_index;
@@ -46,33 +55,45 @@
     }
 };
 
-template <typename Polygon, typename Section>
-struct get_section<polygon_tag, Polygon, Section>
+template <typename Polygon, typename Section, bool IsConst>
+struct get_section<polygon_tag, Polygon, Section, IsConst>
 {
- typedef typename boost::range_const_iterator
+ typedef typename add_const_if_c
+ <
+ IsConst,
+ Polygon
+ >::type polygon_type;
+
+ typedef typename boost::range_iterator
         <
- typename geometry::range_type<Polygon>::type
+ typename add_const_if_c
+ <
+ IsConst,
+ typename geometry::range_type<Polygon>::type
+ >::type
>::type iterator_type;
 
- static inline void apply(Polygon const& polygon, Section const& section,
+ static inline void apply(polygon_type& polygon, Section const& section,
                 iterator_type& begin, iterator_type& end)
     {
- typedef typename geometry::ring_type<Polygon>::type ring_type;
- ring_type const& ring = section.ring_index < 0
- ? geometry::exterior_ring(polygon)
- : geometry::interior_rings(polygon)[section.ring_index];
+ typename add_const_if_c
+ <
+ IsConst,
+ typename geometry::ring_type<Polygon>::type
+ >::type& ring = section.ring_index < 0
+ ? geometry::exterior_ring(polygon)
+ : geometry::interior_rings(polygon)[section.ring_index];
 
         begin = boost::begin(ring) + section.begin_index;
         end = boost::begin(ring) + section.end_index + 1;
     }
 };
 
+
 } // namespace dispatch
 #endif
 
 
-
-
 /*!
     \brief Get iterators for a specified section
     \ingroup sectionalize
@@ -82,18 +103,16 @@
     \param section structure with section
     \param begin begin-iterator (const iterator over points of section)
     \param end end-iterator (const iterator over points of section)
- \todo Create non-const version as well
-
  */
 template <typename Geometry, typename Section>
 inline void get_section(Geometry const& geometry, Section const& section,
- typename boost::range_const_iterator
+ typename boost::range_iterator
         <
- typename geometry::range_type<Geometry>::type
+ typename geometry::range_type<Geometry>::type const
>::type& begin,
- typename boost::range_const_iterator
+ typename boost::range_iterator
         <
- typename geometry::range_type<Geometry>::type
+ typename geometry::range_type<Geometry>::type const
>::type& end)
 {
     concept::check<Geometry const>();
@@ -102,13 +121,37 @@
         <
             typename tag<Geometry>::type,
             Geometry,
- Section
+ Section,
+ true
>::apply(geometry, section, begin, end);
 }
 
 
+// non const version
+template <typename Geometry, typename Section>
+inline void get_section(Geometry& geometry, Section const& section,
+ typename boost::range_iterator
+ <
+ typename geometry::range_type<Geometry>::type
+ >::type& begin,
+ typename boost::range_iterator
+ <
+ typename geometry::range_type<Geometry>::type
+ >::type& end)
+{
+ concept::check<Geometry>();
+
+ dispatch::get_section
+ <
+ typename tag<Geometry>::type,
+ Geometry,
+ Section,
+ false
+ >::apply(geometry, section, begin, end);
+}
 
 
 }} // namespace boost::geometry
 
+
 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_SECTIONS_GET_SECTION_HPP

Modified: sandbox/geometry/boost/geometry/algorithms/distance.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/algorithms/distance.hpp (original)
+++ sandbox/geometry/boost/geometry/algorithms/distance.hpp 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -26,6 +26,9 @@
 #include <boost/geometry/strategies/distance_result.hpp>
 #include <boost/geometry/algorithms/within.hpp>
 
+
+#include <boost/geometry/util/math.hpp>
+
 /*!
 \defgroup distance distance: calculate distance between two geometries
 The distance algorithm returns the distance between two geometries.
@@ -99,19 +102,19 @@
 template<typename Point, typename Range, typename PPStrategy, typename PSStrategy>
 struct point_to_range
 {
- typedef typename PPStrategy::return_type return_type;
+ typedef typename PSStrategy::return_type return_type;
 
     static inline return_type apply(Point const& point, Range const& range,
             PPStrategy const& pp_strategy, PSStrategy const& ps_strategy)
     {
- typedef segment<typename point_type<Range>::type const> segment_type;
+ return_type const zero = return_type(0);
 
         if (boost::size(range) == 0)
         {
- return return_type(0);
+ return zero;
         }
 
- // line of one point: return point square_distance
+ // line of one point: return point distance
         typedef typename boost::range_iterator<Range const>::type iterator_type;
         iterator_type it = boost::begin(range);
         iterator_type prev = it++;
@@ -120,27 +123,32 @@
             return pp_strategy.apply(point, *boost::begin(range));
         }
 
+ // Create efficient strategy
+ typedef typename strategy::distance::services::comparable_type<PSStrategy>::type eps_strategy_type;
+ eps_strategy_type eps_strategy = strategy::distance::services::get_comparable<PSStrategy>::apply(ps_strategy);
 
         // start with first segment distance
- return_type d = ps_strategy.apply(point, *prev, *it);
+ return_type d = eps_strategy.apply(point, *prev, *it);
+ return_type rd = ps_strategy.apply(point, *prev, *it);
 
         // check if other segments are closer
         prev = it++;
         while(it != boost::end(range))
         {
- return_type ds = ps_strategy.apply(point, *prev, *it);
- if (geometry::close_to_zero(ds))
+ return_type const ds = ps_strategy.apply(point, *prev, *it);
+ if (geometry::math::equals(ds, zero))
             {
- return return_type(0);
+ return ds;
             }
             else if (ds < d)
             {
                 d = ds;
+ return_type rd = ps_strategy.apply(point, *prev, *it);
             }
             prev = it++;
         }
 
- return d;
+ return rd;
     }
 };
 
@@ -422,6 +430,9 @@
 inline typename Strategy::return_type distance(Geometry1 const& geometry1,
             Geometry2 const& geometry2, Strategy const& strategy)
 {
+ concept::check<Geometry1 const>();
+ concept::check<Geometry2 const>();
+
     return boost::mpl::if_
         <
             typename geometry::reverse_dispatch<Geometry1, Geometry2>::type,

Modified: sandbox/geometry/boost/geometry/algorithms/overlaps.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/algorithms/overlaps.hpp (original)
+++ sandbox/geometry/boost/geometry/algorithms/overlaps.hpp 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -22,6 +22,8 @@
 
 #include <cstddef>
 
+#include <boost/mpl/assert.hpp>
+
 #include <boost/geometry/core/access.hpp>
 
 #include <boost/geometry/geometries/concepts/check.hpp>
@@ -142,11 +144,13 @@
 }} // namespace detail::overlaps
 #endif // DOXYGEN_NO_DETAIL
 
+//struct not_implemented_for_this_geometry_type : public boost::false_type {};
 
 #ifndef DOXYGEN_NO_DISPATCH
 namespace dispatch
 {
 
+
 template
 <
     typename Tag1,
@@ -155,7 +159,13 @@
     typename Geometry2
>
 struct overlaps
-{};
+{
+ BOOST_MPL_ASSERT_MSG
+ (
+ false, NOT_OR_NOT_YET_IMPLEMENT_FOR_THIS_GEOMETRY_TYPE
+ , (types<Geometry1, Geometry2>)
+ );
+};
 
 
 template <typename Box1, typename Box2>

Modified: sandbox/geometry/boost/geometry/algorithms/simplify.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/algorithms/simplify.hpp (original)
+++ sandbox/geometry/boost/geometry/algorithms/simplify.hpp 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -73,9 +73,9 @@
 template<typename Range, typename Strategy>
 struct simplify_range_inserter
 {
- template <typename OutputIterator>
+ template <typename OutputIterator, typename Distance>
     static inline void apply(Range const& range, OutputIterator out,
- double max_distance, Strategy const& strategy)
+ Distance const& max_distance, Strategy const& strategy)
     {
         if (boost::size(range) <= 2 || max_distance < 0)
         {
@@ -92,8 +92,9 @@
 template<typename Range, typename Strategy>
 struct simplify_copy
 {
+ template <typename Distance>
     static inline void apply(Range const& range, Range& out,
- double max_distance, Strategy const& strategy)
+ Distance const& max_distance, Strategy const& strategy)
     {
         std::copy
             (
@@ -106,8 +107,9 @@
 template<typename Range, typename Strategy, std::size_t Minimum>
 struct simplify_range
 {
+ template <typename Distance>
     static inline void apply(Range const& range, Range& out,
- double max_distance, Strategy const& strategy)
+ Distance const& max_distance, Strategy const& strategy)
     {
         // Call do_container for a linestring / ring
 
@@ -144,8 +146,9 @@
 template<typename Polygon, typename Strategy>
 struct simplify_polygon
 {
+ template <typename Distance>
     static inline void apply(Polygon const& poly_in, Polygon& poly_out,
- double max_distance, Strategy const& strategy)
+ Distance const& max_distance, Strategy const& strategy)
     {
         typedef typename ring_type<Polygon>::type ring_type;
 
@@ -198,8 +201,9 @@
 template <typename Point, typename Strategy>
 struct simplify<point_tag, Point, Strategy>
 {
+ template <typename Distance>
     static inline void apply(Point const& point, Point& out,
- double max_distance, Strategy const& strategy)
+ Distance const& max_distance, Strategy const& strategy)
     {
         copy_coordinates(point, out);
     }
@@ -275,9 +279,9 @@
     \param strategy simplify strategy to be used for simplification, might
         include point-distance strategy
  */
-template<typename Geometry, typename Strategy>
+template<typename Geometry, typename Distance, typename Strategy>
 inline void simplify(Geometry const& geometry, Geometry& out,
- double max_distance, Strategy const& strategy)
+ Distance const& max_distance, Strategy const& strategy)
 {
     concept::check<Geometry>();
 
@@ -312,21 +316,15 @@
     \line {
     \until }
  */
-template<typename Geometry>
+template<typename Geometry, typename Distance>
 inline void simplify(Geometry const& geometry, Geometry& out,
- double max_distance)
+ Distance const& max_distance)
 {
     concept::check<Geometry>();
 
     typedef typename point_type<Geometry>::type point_type;
- typedef typename cs_tag<point_type>::type cs_tag;
- typedef typename strategy_distance_segment
- <
- cs_tag,
- cs_tag,
- point_type,
- point_type
- >::type ds_strategy_type;
+ typedef typename default_distance_strategy_segment
+ <point_type>::type ds_strategy_type;
 
     typedef strategy::simplify::douglas_peucker
         <
@@ -354,9 +352,9 @@
     \line {
     \until }
  */
-template<typename Geometry, typename OutputIterator, typename Strategy>
+template<typename Geometry, typename OutputIterator, typename Distance, typename Strategy>
 inline void simplify_inserter(Geometry const& geometry, OutputIterator out,
- double max_distance, Strategy const& strategy)
+ Distance const& max_distance, Strategy const& strategy)
 {
     concept::check<Geometry const>();
     BOOST_CONCEPT_ASSERT( (geometry::concept::SimplifyStrategy<Strategy>) );
@@ -377,9 +375,9 @@
     \param max_distance distance (in units of input coordinates) of a vertex
         to other segments to be removed
  */
-template<typename Geometry, typename OutputIterator>
+template<typename Geometry, typename OutputIterator, typename Distance>
 inline void simplify_inserter(Geometry const& geometry, OutputIterator out,
- double max_distance)
+ Distance const& max_distance)
 {
     typedef typename point_type<Geometry>::type point_type;
 

Modified: sandbox/geometry/boost/geometry/core/coordinate_type.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/core/coordinate_type.hpp (original)
+++ sandbox/geometry/boost/geometry/core/coordinate_type.hpp 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -13,6 +13,7 @@
 #include <boost/type_traits/remove_const.hpp>
 
 #include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/util/promote_floating_point.hpp>
 
 
 namespace boost { namespace geometry
@@ -38,19 +39,19 @@
 namespace core_dispatch
 {
 
-template <typename GeometryTag, typename G>
+template <typename GeometryTag, typename Geometry>
 struct coordinate_type
 {
- typedef typename point_type<GeometryTag, G>::type point_type;
+ typedef typename point_type<GeometryTag, Geometry>::type point_type;
 
     // Call its own specialization on point-tag
     typedef typename coordinate_type<point_tag, point_type>::type type;
 };
 
-template <typename P>
-struct coordinate_type<point_tag, P>
+template <typename Point>
+struct coordinate_type<point_tag, Point>
 {
- typedef typename traits::coordinate_type<P>::type type;
+ typedef typename traits::coordinate_type<Point>::type type;
 };
 
 } // namespace core_dispatch
@@ -60,17 +61,27 @@
     \brief Meta-function which defines coordinate type (int, float, double, etc) of any geometry
     \ingroup core
 */
-template <typename G>
+template <typename Geometry>
 struct coordinate_type
 {
- typedef typename boost::remove_const<G>::type ncg;
     typedef typename core_dispatch::coordinate_type
         <
- typename tag<G>::type,
- ncg
+ typename tag<Geometry>::type,
+ typename boost::remove_const<Geometry>::type
+ >::type type;
+};
+
+template <typename Geometry>
+struct fp_coordinate_type
+{
+ typedef typename promote_floating_point
+ <
+ typename coordinate_type<Geometry>::type
>::type type;
 };
 
+
 }} // namespace boost::geometry
 
+
 #endif // BOOST_GEOMETRY_CORE_COORDINATE_TYPE_HPP

Modified: sandbox/geometry/boost/geometry/core/radian_access.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/core/radian_access.hpp (original)
+++ sandbox/geometry/boost/geometry/core/radian_access.hpp 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -17,11 +17,13 @@
 
 #include <boost/geometry/core/access.hpp>
 #include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/core/coordinate_type.hpp>
 
 
 #include <boost/geometry/util/math.hpp>
 
 
+
 namespace boost { namespace geometry
 {
 
@@ -33,7 +35,7 @@
 template<std::size_t Dimension, typename Geometry>
 struct degree_radian_converter
 {
- typedef typename coordinate_type<Geometry>::type coordinate_type;
+ typedef typename fp_coordinate_type<Geometry>::type coordinate_type;
 
     static inline coordinate_type get(Geometry const& geometry)
     {
@@ -58,7 +60,7 @@
 template <std::size_t Dimension, typename Geometry, typename DegreeOrRadian>
 struct radian_access
 {
- typedef typename coordinate_type<Geometry>::type coordinate_type;
+ typedef typename fp_coordinate_type<Geometry>::type coordinate_type;
 
     static inline coordinate_type get(Geometry const& geometry)
     {
@@ -111,7 +113,7 @@
         e.g. spherical or geographic coordinate systems
 */
 template <std::size_t Dimension, typename Geometry>
-inline typename coordinate_type<Geometry>::type get_as_radian(Geometry const& geometry)
+inline typename fp_coordinate_type<Geometry>::type get_as_radian(Geometry const& geometry)
 {
     return detail::radian_access<Dimension, Geometry,
             typename coordinate_system<Geometry>::type>::get(geometry);
@@ -132,7 +134,7 @@
 */
 template <std::size_t Dimension, typename Geometry>
 inline void set_from_radian(Geometry& geometry,
- const typename coordinate_type<Geometry>::type& radians)
+ typename fp_coordinate_type<Geometry>::type const& radians)
 {
     detail::radian_access<Dimension, Geometry,
             typename coordinate_system<Geometry>::type>::set(geometry, radians);

Modified: sandbox/geometry/boost/geometry/extensions/gis/geographic/strategies/andoyer.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/extensions/gis/geographic/strategies/andoyer.hpp (original)
+++ sandbox/geometry/boost/geometry/extensions/gis/geographic/strategies/andoyer.hpp 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -19,104 +19,172 @@
 
 namespace boost { namespace geometry
 {
-namespace strategy
+
+namespace strategy { namespace distance
 {
 
- namespace distance
- {
 
+/*!
+ \brief Point-point distance approximation taking flattening into account
+ \ingroup distance
+ \tparam P1 first point type
+ \tparam P2 optional second point type
+ \author After Andoyer, 19xx, republished 1950, republished by Meeus, 1999
+ \note Although not so well-known, the approximation is very good: in all cases the results
+ are about the same as Vincenty. In my (Barend's) testcases the results didn't differ more than 6 m
+ \see http://nacc.upc.es/tierra/node16.html
+ \see http://sci.tech-archive.net/Archive/sci.geo.satellite-nav/2004-12/2724.html
+ \see http://home.att.net/~srschmitt/great_circle_route.html (implementation)
+ \see http://www.codeguru.com/Cpp/Cpp/algorithms/article.php/c5115 (implementation)
+ \see http://futureboy.homeip.net/frinksamp/navigation.frink (implementation)
+ \see http://www.voidware.com/earthdist.htm (implementation)
+*/
+template
+<
+ typename P1,
+ typename P2 = P1
+ // calculation_type
+>
+class andoyer
+{
+ public :
+ typedef P1 first_point_type;
+ typedef P2 second_point_type;
+ typedef double return_type;
+
+ andoyer()
+ : m_ellipsoid()
+ {}
+
+ explicit inline andoyer(double f)
+ : m_ellipsoid(f)
+ {}
+
+ explicit inline andoyer(geometry::detail::ellipsoid const& e)
+ : m_ellipsoid(e)
+ {}
+
+
+ inline return_type apply(P1 const& p1, P2 const& p2) const
+ {
+ return calc(get_as_radian<0>(p1), get_as_radian<1>(p1),
+ get_as_radian<0>(p2), get_as_radian<1>(p2));
+ }
+
+ inline geometry::detail::ellipsoid ellipsoid() const
+ {
+ return m_ellipsoid;
+ }
+
+
+ private :
+ typedef typename coordinate_type<P1>::type T1;
+ typedef typename coordinate_type<P2>::type T2;
+ geometry::detail::ellipsoid m_ellipsoid;
 
- /*!
- \brief Point-point distance approximation taking flattening into account
- \ingroup distance
- \tparam P1 first point type
- \tparam P2 optional second point type
- \author After Andoyer, 19xx, republished 1950, republished by Meeus, 1999
- \note Although not so well-known, the approximation is very good: in all cases the results
- are about the same as Vincenty. In my (Barend's) testcases the results didn't differ more than 6 m
- \see http://nacc.upc.es/tierra/node16.html
- \see http://sci.tech-archive.net/Archive/sci.geo.satellite-nav/2004-12/2724.html
- \see http://home.att.net/~srschmitt/great_circle_route.html (implementation)
- \see http://www.codeguru.com/Cpp/Cpp/algorithms/article.php/c5115 (implementation)
- \see http://futureboy.homeip.net/frinksamp/navigation.frink (implementation)
- \see http://www.voidware.com/earthdist.htm (implementation)
- */
- template <typename P1, typename P2 = P1>
- class andoyer
+ inline return_type calc(T1 const& lon1, T1 const& lat1, T2 const& lon2, T2 const& lat2) const
         {
- public :
- //typedef spherical_distance return_type;
- typedef P1 first_point_type;
- typedef P2 second_point_type;
- typedef double return_type;
-
- andoyer()
- : m_ellipsoid()
- {}
- andoyer(double f)
- : m_ellipsoid(f)
- {}
-
- inline return_type apply(P1 const& p1, P2 const& p2) const
- {
- return calc(get_as_radian<0>(p1), get_as_radian<1>(p1),
- get_as_radian<0>(p2), get_as_radian<1>(p2));
- }
-
-
- private :
- typedef typename coordinate_type<P1>::type T1;
- typedef typename coordinate_type<P2>::type T2;
- geometry::detail::ellipsoid m_ellipsoid;
-
- inline return_type calc(T1 const& lon1, T1 const& lat1, T2 const& lon2, T2 const& lat2) const
- {
- typedef double calculation_type;
- calculation_type G = (lat1 - lat2) / 2.0;
- calculation_type lambda = (lon1 - lon2) / 2.0;
-
- if (geometry::math::equals(lambda, 0.0)
- && geometry::math::equals(G, 0.0))
- {
- return 0.0;
- }
-
- calculation_type F = (lat1 + lat2) / 2.0;
-
- calculation_type sinG2 = math::sqr(sin(G));
- calculation_type cosG2 = math::sqr(cos(G));
- calculation_type sinF2 = math::sqr(sin(F));
- calculation_type cosF2 = math::sqr(cos(F));
- calculation_type sinL2 = math::sqr(sin(lambda));
- calculation_type cosL2 = math::sqr(cos(lambda));
-
- calculation_type S = sinG2 * cosL2 + cosF2 * sinL2;
- calculation_type C = cosG2 * cosL2 + sinF2 * sinL2;
-
- if (geometry::math::equals(S, 0.0) || geometry::math::equals(C, 0.0))
- {
- return 0.0;
- }
-
- calculation_type omega = atan(sqrt(S / C));
- calculation_type r = sqrt(S * C) / omega; // not sure if this is r or greek nu
-
- calculation_type D = 2.0 * omega * m_ellipsoid.a();
- calculation_type H1 = (3 * r - 1.0) / (2.0 * C);
- calculation_type H2 = (3 * r + 1.0) / (2.0 * S);
-
- return return_type(D
- * (1.0 + m_ellipsoid.f() * H1 * sinF2 * cosG2
- - m_ellipsoid.f() * H2 * cosF2 * sinG2));
- }
- };
+ typedef double calculation_type;
+ calculation_type G = (lat1 - lat2) / 2.0;
+ calculation_type lambda = (lon1 - lon2) / 2.0;
+
+ if (geometry::math::equals(lambda, 0.0)
+ && geometry::math::equals(G, 0.0))
+ {
+ return 0.0;
+ }
+
+ calculation_type F = (lat1 + lat2) / 2.0;
+
+ calculation_type sinG2 = math::sqr(sin(G));
+ calculation_type cosG2 = math::sqr(cos(G));
+ calculation_type sinF2 = math::sqr(sin(F));
+ calculation_type cosF2 = math::sqr(cos(F));
+ calculation_type sinL2 = math::sqr(sin(lambda));
+ calculation_type cosL2 = math::sqr(cos(lambda));
+
+ calculation_type S = sinG2 * cosL2 + cosF2 * sinL2;
+ calculation_type C = cosG2 * cosL2 + sinF2 * sinL2;
+
+ if (geometry::math::equals(S, 0.0) || geometry::math::equals(C, 0.0))
+ {
+ return 0.0;
+ }
+
+ calculation_type omega = atan(sqrt(S / C));
+ calculation_type r = sqrt(S * C) / omega; // not sure if this is r or greek nu
+
+ calculation_type D = 2.0 * omega * m_ellipsoid.a();
+ calculation_type H1 = (3 * r - 1.0) / (2.0 * C);
+ calculation_type H2 = (3 * r + 1.0) / (2.0 * S);
+
+ return return_type(D
+ * (1.0 + m_ellipsoid.f() * H1 * sinF2 * cosG2
+ - m_ellipsoid.f() * H2 * cosF2 * sinG2));
+ }
+};
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+namespace services
+{
+
+template <typename Point1, typename Point2>
+struct tag<strategy::distance::andoyer<Point1, Point2> >
+{
+ typedef strategy_tag_distance_point_point type;
+};
+
 
+template <typename Point1, typename Point2, typename P1, typename P2>
+struct similar_type<andoyer<Point1, Point2>, P1, P2>
+{
+ typedef andoyer<P1, P2> type;
+};
 
 
- } // namespace distance
+template <typename Point1, typename Point2, typename P1, typename P2>
+struct get_similar<andoyer<Point1, Point2>, P1, P2>
+{
+ static inline andoyer<P1, P2> apply(andoyer<Point1, Point2> const& input)
+ {
+ return andoyer<P1, P2>(input.ellipsoid());
+ }
+};
 
+template <typename Point1, typename Point2>
+struct comparable_type<andoyer<Point1, Point2> >
+{
+ typedef andoyer<Point1, Point2> type;
+};
+
+
+template <typename Point1, typename Point2>
+struct get_comparable<andoyer<Point1, Point2> >
+{
+ static inline andoyer<Point1, Point2> apply(andoyer<Point1, Point2> const& input)
+ {
+ return input;
+ }
+};
+
+template <typename Point1, typename Point2>
+struct result_from_distance<andoyer<Point1, Point2> >
+{
+ template <typename T>
+ static inline typename andoyer<Point1, Point2>::return_type apply(andoyer<Point1, Point2> const& , T const& value)
+ {
+ return value;
+ }
+};
+
+
+} // namespace services
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::distance
 
-} // namespace strategy
 
 
 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
@@ -133,7 +201,8 @@
     typedef strategy_tag_distance_point_point type;
 };
 
-#endif
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
 
 
 }} // namespace boost::geometry

Modified: sandbox/geometry/boost/geometry/extensions/gis/geographic/strategies/vincenty.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/extensions/gis/geographic/strategies/vincenty.hpp (original)
+++ sandbox/geometry/boost/geometry/extensions/gis/geographic/strategies/vincenty.hpp 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -19,118 +19,186 @@
 
 namespace boost { namespace geometry
 {
-namespace strategy
+
+namespace strategy { namespace distance
 {
 
- namespace distance
- {
+/*!
+ \brief Distance calculation formulae on latlong coordinates, after Vincenty, 1975
+ \ingroup distance
+ \tparam P1 first point type
+ \tparam P2 optional second point type
+ \author See http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf
+ \author Adapted from various implementations to get it close to the original document
+ - http://www.movable-type.co.uk/scripts/LatLongVincenty.html
+ - http://exogen.case.edu/projects/geopy/source/geopy.distance.html
+ - http://futureboy.homeip.net/fsp/colorize.fsp?fileName=navigation.frink
+
+*/
+template <typename P1, typename P2 = P1>
+class vincenty
+{
+ public :
+ //typedef spherical_distance return_type;
+ typedef P1 first_point_type;
+ typedef P2 second_point_type;
+ typedef double return_type;
+
+ inline vincenty()
+ {}
+
+ explicit inline vincenty(geometry::detail::ellipsoid const& e)
+ : m_ellipsoid(e)
+ {}
 
- /*!
- \brief Distance calculation formulae on latlong coordinates, after Vincenty, 1975
- \ingroup distance
- \tparam P1 first point type
- \tparam P2 optional second point type
- \author See http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf
- \author Adapted from various implementations to get it close to the original document
- - http://www.movable-type.co.uk/scripts/LatLongVincenty.html
- - http://exogen.case.edu/projects/geopy/source/geopy.distance.html
- - http://futureboy.homeip.net/fsp/colorize.fsp?fileName=navigation.frink
-
- */
- template <typename P1, typename P2 = P1>
- class vincenty
+ inline return_type apply(P1 const& p1, P2 const& p2) const
         {
- public :
- //typedef spherical_distance return_type;
- typedef P1 first_point_type;
- typedef P2 second_point_type;
- typedef double return_type;
-
- inline return_type apply(P1 const& p1, P2 const& p2) const
- {
- return calculate(get_as_radian<0>(p1), get_as_radian<1>(p1),
- get_as_radian<0>(p2), get_as_radian<1>(p2));
- }
-
- private :
- typedef typename coordinate_type<P1>::type T1;
- typedef typename coordinate_type<P2>::type T2;
- geometry::detail::ellipsoid m_ellipsoid;
-
- inline return_type calculate(T1 const& lon1, T1 const& lat1, T2 const& lon2, T2 const& lat2) const
- {
- // lambda: difference in longitude on an auxiliary sphere
- double L = lon2 - lon1;
- double lambda = L;
-
- if (L < -math::pi) L += math::two_pi;
- if (L > math::pi) L -= math::two_pi;
-
- if (lat1 == lat2 && lon1 == lon2)
- {
- return return_type(0);
- }
-
- // U: reduced latitude, defined by tan U = (1-f) tan phi
- double U1 = atan((1-m_ellipsoid.f()) * tan(lat1)); // above (1)
- double U2 = atan((1-m_ellipsoid.f()) * tan(lat2)); // above (1)
-
- double cos_U1 = cos(U1);
- double cos_U2 = cos(U2);
- double sin_U1 = sin(U1);
- double sin_U2 = sin(U2);
-
- // alpha: azimuth of the geodesic at the equator
- double cos2_alpha;
- double sin_alpha;
-
- // sigma: angular distance p1,p2 on the sphere
- // sigma1: angular distance on the sphere from the equator to p1
- // sigma_m: angular distance on the sphere from the equator to the midpoint of the line
- double sigma;
- double sin_sigma;
- double cos2_sigma_m;
-
- double previous_lambda;
-
- do
- {
- previous_lambda = lambda; // (13)
- double sin_lambda = sin(lambda);
- double cos_lambda = cos(lambda);
- sin_sigma = sqrt(math::sqr(cos_U2 * sin_lambda) + math::sqr(cos_U1 * sin_U2 - sin_U1 * cos_U2 * cos_lambda)); // (14)
- double cos_sigma = sin_U1 * sin_U2 + cos_U1 * cos_U2 * cos_lambda; // (15)
- sin_alpha = cos_U1 * cos_U2 * sin_lambda / sin_sigma; // (17)
- cos2_alpha = 1.0 - math::sqr(sin_alpha);
- cos2_sigma_m = cos2_alpha == 0 ? 0 : cos_sigma - 2.0 * sin_U1 * sin_U2 / cos2_alpha; // (18)
-
- double C = m_ellipsoid.f()/16.0 * cos2_alpha * (4.0 + m_ellipsoid.f() * (4.0 - 3.0 * cos2_alpha)); // (10)
- sigma = atan2(sin_sigma, cos_sigma); // (16)
- lambda = L + (1.0 - C) * m_ellipsoid.f() * sin_alpha *
- (sigma + C * sin_sigma * ( cos2_sigma_m + C * cos_sigma * (-1.0 + 2.0 * math::sqr(cos2_sigma_m)))); // (11)
-
- } while (fabs(previous_lambda - lambda) > 1e-12 && fabs(lambda) < math::pi);
-
- double sqr_u = cos2_alpha * (math::sqr(m_ellipsoid.a()) - math::sqr(m_ellipsoid.b())) / math::sqr(m_ellipsoid.b()); // above (1)
-
- double A = 1.0 + sqr_u/16384.0 * (4096 + sqr_u * (-768.0 + sqr_u * (320.0 - 175.0 * sqr_u))); // (3)
- double B = sqr_u/1024.0 * (256.0 + sqr_u * ( -128.0 + sqr_u * (74.0 - 47.0 * sqr_u))); // (4)
- double delta_sigma = B * sin_sigma * ( cos2_sigma_m + (B/4.0) * (cos(sigma)* (-1.0 + 2.0 * cos2_sigma_m)
- - (B/6.0) * cos2_sigma_m * (-3.0 + 4.0 * math::sqr(sin_sigma)) * (-3.0 + 4.0 * cos2_sigma_m))); // (6)
-
- double dist = m_ellipsoid.b() * A * (sigma - delta_sigma); // (19)
-
- return return_type(dist);
- }
- };
+ return calculate(get_as_radian<0>(p1), get_as_radian<1>(p1),
+ get_as_radian<0>(p2), get_as_radian<1>(p2));
+ }
+
+ inline geometry::detail::ellipsoid ellipsoid() const
+ {
+ return m_ellipsoid;
+ }
+
+
+ private :
+ typedef typename coordinate_type<P1>::type T1;
+ typedef typename coordinate_type<P2>::type T2;
+ geometry::detail::ellipsoid m_ellipsoid;
+
+ inline return_type calculate(T1 const& lon1, T1 const& lat1, T2 const& lon2, T2 const& lat2) const
+ {
+ // lambda: difference in longitude on an auxiliary sphere
+ double L = lon2 - lon1;
+ double lambda = L;
+
+ if (L < -math::pi) L += math::two_pi;
+ if (L > math::pi) L -= math::two_pi;
+
+ if (lat1 == lat2 && lon1 == lon2)
+ {
+ return return_type(0);
+ }
+
+ // U: reduced latitude, defined by tan U = (1-f) tan phi
+ double U1 = atan((1-m_ellipsoid.f()) * tan(lat1)); // above (1)
+ double U2 = atan((1-m_ellipsoid.f()) * tan(lat2)); // above (1)
+
+ double cos_U1 = cos(U1);
+ double cos_U2 = cos(U2);
+ double sin_U1 = sin(U1);
+ double sin_U2 = sin(U2);
+
+ // alpha: azimuth of the geodesic at the equator
+ double cos2_alpha;
+ double sin_alpha;
+
+ // sigma: angular distance p1,p2 on the sphere
+ // sigma1: angular distance on the sphere from the equator to p1
+ // sigma_m: angular distance on the sphere from the equator to the midpoint of the line
+ double sigma;
+ double sin_sigma;
+ double cos2_sigma_m;
+
+ double previous_lambda;
+
+ do
+ {
+ previous_lambda = lambda; // (13)
+ double sin_lambda = sin(lambda);
+ double cos_lambda = cos(lambda);
+ sin_sigma = sqrt(math::sqr(cos_U2 * sin_lambda) + math::sqr(cos_U1 * sin_U2 - sin_U1 * cos_U2 * cos_lambda)); // (14)
+ double cos_sigma = sin_U1 * sin_U2 + cos_U1 * cos_U2 * cos_lambda; // (15)
+ sin_alpha = cos_U1 * cos_U2 * sin_lambda / sin_sigma; // (17)
+ cos2_alpha = 1.0 - math::sqr(sin_alpha);
+ cos2_sigma_m = cos2_alpha == 0 ? 0 : cos_sigma - 2.0 * sin_U1 * sin_U2 / cos2_alpha; // (18)
+
+ double C = m_ellipsoid.f()/16.0 * cos2_alpha * (4.0 + m_ellipsoid.f() * (4.0 - 3.0 * cos2_alpha)); // (10)
+ sigma = atan2(sin_sigma, cos_sigma); // (16)
+ lambda = L + (1.0 - C) * m_ellipsoid.f() * sin_alpha *
+ (sigma + C * sin_sigma * ( cos2_sigma_m + C * cos_sigma * (-1.0 + 2.0 * math::sqr(cos2_sigma_m)))); // (11)
+
+ } while (fabs(previous_lambda - lambda) > 1e-12 && fabs(lambda) < math::pi);
+
+ double sqr_u = cos2_alpha * (math::sqr(m_ellipsoid.a()) - math::sqr(m_ellipsoid.b())) / math::sqr(m_ellipsoid.b()); // above (1)
+
+ double A = 1.0 + sqr_u/16384.0 * (4096 + sqr_u * (-768.0 + sqr_u * (320.0 - 175.0 * sqr_u))); // (3)
+ double B = sqr_u/1024.0 * (256.0 + sqr_u * ( -128.0 + sqr_u * (74.0 - 47.0 * sqr_u))); // (4)
+ double delta_sigma = B * sin_sigma * ( cos2_sigma_m + (B/4.0) * (cos(sigma)* (-1.0 + 2.0 * cos2_sigma_m)
+ - (B/6.0) * cos2_sigma_m * (-3.0 + 4.0 * math::sqr(sin_sigma)) * (-3.0 + 4.0 * cos2_sigma_m))); // (6)
+
+ double dist = m_ellipsoid.b() * A * (sigma - delta_sigma); // (19)
+
+ return return_type(dist);
+ }
+};
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+namespace services
+{
+
+template <typename Point1, typename Point2>
+struct tag<strategy::distance::vincenty<Point1, Point2> >
+{
+ typedef strategy_tag_distance_point_point type;
+};
+
+
+template <typename Point1, typename Point2, typename P1, typename P2>
+struct similar_type<vincenty<Point1, Point2>, P1, P2>
+{
+ typedef vincenty<P1, P2> type;
+};
+
+
+template <typename Point1, typename Point2, typename P1, typename P2>
+struct get_similar<vincenty<Point1, Point2>, P1, P2>
+{
+ static inline vincenty<P1, P2> apply(vincenty<Point1, Point2> const& input)
+ {
+ return vincenty<P1, P2>(input.ellipsoid());
+ }
+};
+
+template <typename Point1, typename Point2>
+struct comparable_type<vincenty<Point1, Point2> >
+{
+ typedef vincenty<Point1, Point2> type;
+};
+
+
+template <typename Point1, typename Point2>
+struct get_comparable<vincenty<Point1, Point2> >
+{
+ static inline vincenty<Point1, Point2> apply(vincenty<Point1, Point2> const& input)
+ {
+ return input;
+ }
+};
+
+template <typename Point1, typename Point2>
+struct result_from_distance<vincenty<Point1, Point2> >
+{
+ template <typename T>
+ static inline typename vincenty<Point1, Point2>::return_type apply(vincenty<Point1, Point2> const& , T const& value)
+ {
+ return value;
+ }
+};
+
+
+} // namespace services
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
 
 
- // We might add a vincenty-like strategy also for point-segment distance, but to calculate the projected point is not trivial
+// We might add a vincenty-like strategy also for point-segment distance, but to calculate the projected point is not trivial
 
- } // namespace distance
 
 
-} // namespace strategy
+}} // namespace strategy::distance
 
 
 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS

Modified: sandbox/geometry/boost/geometry/multi/algorithms/detail/sections/get_section.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/multi/algorithms/detail/sections/get_section.hpp (original)
+++ sandbox/geometry/boost/geometry/multi/algorithms/detail/sections/get_section.hpp 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -28,15 +28,24 @@
 {
 
 
-template <typename MultiPolygon, typename Section>
-struct get_section<multi_polygon_tag, MultiPolygon, Section>
+template <typename MultiPolygon, typename Section, bool IsConst>
+struct get_section<multi_polygon_tag, MultiPolygon, Section, IsConst>
 {
     typedef typename boost::range_iterator
         <
- typename geometry::range_type<MultiPolygon>::type const
+ typename add_const_if_c
+ <
+ IsConst,
+ typename geometry::range_type<MultiPolygon>::type
+ >::type
>::type iterator_type;
 
- static inline void apply(MultiPolygon const& multi_polygon,
+ static inline void apply(
+ typename add_const_if_c
+ <
+ IsConst,
+ MultiPolygon
+ >::type const& multi_polygon,
                 Section const& section,
                 iterator_type& begin, iterator_type& end)
     {
@@ -49,7 +58,8 @@
             <
                 polygon_tag,
                 typename boost::range_value<MultiPolygon>::type,
- Section
+ Section,
+ IsConst
>::apply(multi_polygon[section.multi_index], section, begin, end);
     }
 };

Modified: sandbox/geometry/boost/geometry/strategies/agnostic/simplify_douglas_peucker.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/strategies/agnostic/simplify_douglas_peucker.hpp (original)
+++ sandbox/geometry/boost/geometry/strategies/agnostic/simplify_douglas_peucker.hpp 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -88,15 +88,20 @@
>
 class douglas_peucker
 {
+public :
+
+ typedef typename strategy::distance::services::comparable_type<PointDistanceStrategy>::type distance_strategy_type;
+ typedef typename distance_strategy_type::return_type return_type;
+
+private :
     typedef detail::douglas_peucker_point<Point> dp_point_type;
     typedef typename std::vector<dp_point_type>::iterator iterator_type;
 
- typedef typename PointDistanceStrategy::return_type return_type;
 
     static inline void consider(iterator_type begin,
                 iterator_type end,
                 return_type const& max_dist, int& n,
- PointDistanceStrategy const& ps_distance_strategy)
+ distance_strategy_type const& ps_distance_strategy)
     {
         std::size_t size = end - begin;
 
@@ -125,7 +130,7 @@
 #endif
 
 
- // Find most distance point, compare to the current segment
+ // Find most far point, compare to the current segment
         //geometry::segment<Point const> s(begin->p, last->p);
         return_type md(-1.0); // any value < 0
         iterator_type candidate;
@@ -166,14 +171,11 @@
 
 public :
 
- typedef PointDistanceStrategy distance_strategy_type;
-
-
     template <typename Range, typename OutputIterator>
     static inline OutputIterator apply(Range const& range,
                     OutputIterator out, double max_distance)
     {
- PointDistanceStrategy strategy;
+ distance_strategy_type strategy;
 
         // Copy coordinates, a vector of references to all points
         std::vector<dp_point_type> ref_candidates(boost::begin(range),
@@ -187,10 +189,9 @@
 
         // Get points, recursively, including them if they are further away
         // than the specified distance
- typedef typename PointDistanceStrategy::return_type return_type;
+ typedef typename distance_strategy_type::return_type return_type;
 
- consider(boost::begin(ref_candidates), boost::end(ref_candidates),
- make_distance_result<return_type>(max_distance), n, strategy);
+ consider(boost::begin(ref_candidates), boost::end(ref_candidates), max_distance, n, strategy);
 
         // Copy included elements to the output
         for(typename std::vector<dp_point_type>::const_iterator it

Modified: sandbox/geometry/boost/geometry/strategies/cartesian/distance_projected_point.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/strategies/cartesian/distance_projected_point.hpp (original)
+++ sandbox/geometry/boost/geometry/strategies/cartesian/distance_projected_point.hpp 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -10,6 +10,7 @@
 #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PROJECTED_POINT_HPP
 
 
+#include <boost/concept_check.hpp>
 #include <boost/mpl/if.hpp>
 #include <boost/type_traits.hpp>
 
@@ -28,7 +29,8 @@
 #include <boost/geometry/util/copy.hpp>
 
 
-// Helper geometry
+// Helper geometries
+#include <boost/geometry/geometries/point.hpp>
 #include <boost/geometry/geometries/segment.hpp>
 
 
@@ -40,7 +42,6 @@
 {
 
 
-
 /*!
     \brief Strategy for distance point to segment
     \ingroup distance
@@ -51,30 +52,65 @@
     \tparam Strategy strategy, optional, defaults to pythagoras
     \par Concepts for Strategy:
     - cartesian_distance operator(Point,Point)
+ \note If the Strategy is a "comparable::pythagoras", this strategy
+ automatically is a comparable projected_point strategy (so without sqrt)
 */
 template
 <
     typename Point,
     typename PointOfSegment,
- typename Strategy = pythagoras
- <
- Point,
- typename point_type<PointOfSegment>::type
- >
+ typename CalculationType = void,
+ typename Strategy = pythagoras<Point, PointOfSegment, CalculationType>
>
-struct projected_point
+class projected_point
 {
+public :
     typedef Point point_type;
     typedef PointOfSegment segment_point_type;
+
     typedef typename select_coordinate_type
         <
             Point,
             PointOfSegment
>::type coordinate_type;
- typedef cartesian_distance<coordinate_type> return_type;
+
+ typedef typename Strategy::return_type return_type;
 
     typedef Strategy point_strategy_type;
 
+private :
+
+ // The three typedefs below are necessary to calculate distances
+ // from segments defined in integer coordinates.
+
+ // Integer coordinates can still result in FP distances.
+ // There is a division, which must be represented in FP.
+ // So promote.
+ typedef typename promote_floating_point<coordinate_type>::type fp_type;
+
+ // A projected point of points in Integer coordinates must be able to be
+ // represented in FP.
+ typedef boost::geometry::point
+ <
+ fp_type,
+ dimension<PointOfSegment>::value,
+ typename coordinate_system<PointOfSegment>::type
+ > fp_point_type;
+
+ // For convenience
+ typedef fp_point_type fp_vector_type;
+
+ // We have to use a strategy using FP coordinates (fp-type) which is
+ // not always the same as Strategy (defined as point_strategy_type)
+ // So we create a "similar" one
+ typedef typename strategy::distance::services::similar_type
+ <
+ point_strategy_type,
+ Point,
+ fp_point_type
+ >::type fp_strategy_type;
+
+public :
 
     inline return_type apply(Point const& p,
                     PointOfSegment const& p1, PointOfSegment const& p2) const
@@ -90,49 +126,148 @@
         RETURN POINT(x1 + b * vx, y1 + b * vy);
         */
 
-
- // Take here the first point type. It should have a default constructor.
- // That is not required for the second point type.
- Point v, w;
+ // v is multiplied below with a (possibly) FP-value, so should be in FP
+ // For consistency we define w also in FP
+ fp_vector_type v, w;
 
         copy_coordinates(p2, v);
         copy_coordinates(p, w);
         subtract_point(v, p1);
         subtract_point(w, p1);
 
- Strategy strategy;
+ point_strategy_type strategy;
+ boost::ignore_unused_variable_warning(strategy);
 
         coordinate_type zero = coordinate_type();
- coordinate_type c1 = dot_product(w, v);
+ fp_type c1 = dot_product(w, v);
         if (c1 <= zero)
         {
             return strategy.apply(p, p1);
         }
- coordinate_type c2 = dot_product(v, v);
+ fp_type c2 = dot_product(v, v);
         if (c2 <= c1)
         {
             return strategy.apply(p, p2);
         }
 
- // Even in case of char's, we have to turn to a point<double/float>
- // because of the division.
- typedef typename geometry::select_most_precise<coordinate_type, double>::type divisor_type;
- divisor_type b = c1 / c2;
-
- // Note that distances with integer coordinates do NOT work because
- // - the project point is integer
- // - if we solve that, the used distance_strategy cannot handle double points
- PointOfSegment projected;
+ // See above, c1 > 0 AND c2 > c1 so: c2 != 0
+ fp_type b = fp_type(c1) / fp_type(c2);
+
+
+ fp_strategy_type fp_strategy
+ = strategy::distance::services::get_similar
+ <
+ point_strategy_type, Point, fp_point_type
+ >::apply(strategy);
+
+ fp_point_type projected;
         copy_coordinates(p1, projected);
         multiply_value(v, b);
         add_point(projected, v);
 
- return strategy.apply(p, projected);
+ //std::cout << "distance " << dsv(p) << " .. " << dsv(projected) << std::endl;
 
+ return fp_strategy.apply(p, projected);
     }
 
 };
 
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+namespace services
+{
+
+template <typename Point, typename PointOfSegment, typename CalculationType, typename Strategy>
+struct tag<projected_point<Point, PointOfSegment, CalculationType, Strategy> >
+{
+ typedef strategy_tag_distance_point_segment type;
+};
+
+
+template
+<
+ typename Point,
+ typename PointOfSegment,
+ typename CalculationType,
+ typename Strategy,
+ typename P1,
+ typename P2
+>
+struct similar_type<projected_point<Point, PointOfSegment, CalculationType, Strategy>, P1, P2>
+{
+ typedef projected_point<P1, P2, CalculationType, Strategy> type;
+};
+
+
+template
+<
+ typename Point,
+ typename PointOfSegment,
+ typename CalculationType,
+ typename Strategy,
+ typename P1,
+ typename P2
+>
+struct get_similar<projected_point<Point, PointOfSegment, CalculationType, Strategy>, P1, P2>
+{
+ static inline typename similar_type
+ <
+ projected_point<Point, PointOfSegment, CalculationType, Strategy>, P1, P2
+ >::type apply(projected_point<Point, PointOfSegment, CalculationType, Strategy> const& )
+ {
+ return projected_point<P1, P2, CalculationType, Strategy>();
+ }
+};
+
+
+template <typename Point, typename PointOfSegment, typename CalculationType, typename Strategy>
+struct comparable_type<projected_point<Point, PointOfSegment, CalculationType, Strategy> >
+{
+ // Define a projected_point strategy with its underlying point-point-strategy
+ // being comparable
+ typedef projected_point
+ <
+ Point,
+ PointOfSegment,
+ CalculationType,
+ typename comparable_type<Strategy>::type
+ > type;
+};
+
+
+template <typename Point, typename PointOfSegment, typename CalculationType, typename Strategy>
+struct get_comparable<projected_point<Point, PointOfSegment, CalculationType, Strategy> >
+{
+ typedef typename comparable_type
+ <
+ projected_point<Point, PointOfSegment, CalculationType, Strategy>
+ >::type comparable_type;
+public :
+ static inline comparable_type apply(projected_point<Point, PointOfSegment, CalculationType, Strategy> const& )
+ {
+ return comparable_type();
+ }
+};
+
+
+template <typename Point, typename PointOfSegment, typename CalculationType, typename Strategy>
+struct result_from_distance<projected_point<Point, PointOfSegment, CalculationType, Strategy> >
+{
+private :
+ typedef typename projected_point<Point, PointOfSegment, CalculationType, Strategy>::return_type return_type;
+public :
+ template <typename T>
+ static inline return_type apply(projected_point<Point, PointOfSegment, CalculationType, Strategy> const& , T const& value)
+ {
+ Strategy s;
+ return result_from_distance<Strategy>::apply(s, value);
+ }
+};
+
+
+} // namespace services
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
 }} // namespace strategy::distance
 
 
@@ -149,6 +284,7 @@
     <
         Point,
         PointOfSegment,
+ void,
         typename strategy_distance
         <
             cartesian_tag, cartesian_tag, Point, segment_point_type

Modified: sandbox/geometry/boost/geometry/strategies/cartesian/distance_pythagoras.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/strategies/cartesian/distance_pythagoras.hpp (original)
+++ sandbox/geometry/boost/geometry/strategies/cartesian/distance_pythagoras.hpp 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -19,6 +19,8 @@
 #include <boost/geometry/strategies/distance_result.hpp>
 
 #include <boost/geometry/util/select_calculation_type.hpp>
+#include <boost/geometry/util/promote_floating_point.hpp>
+
 #include <boost/geometry/util/copy.hpp>
 
 
@@ -57,8 +59,12 @@
 }
 #endif // DOXYGEN_NO_DETAIL
 
+
+namespace comparable
+{
+
 /*!
- \brief Strategy for distance point to point: pythagoras
+ \brief Strategy for comparable distance point to point: comparable_pythagoras
     \ingroup distance
     \tparam Point1 first point type
     \tparam Point2 optional, second point type, defaults to first point type
@@ -74,17 +80,16 @@
 struct pythagoras
 {
     typedef typename select_calculation_type
- <
- Point1,
- Point2,
- CalculationType
- >::type calculation_type;
+ <
+ Point1,
+ Point2,
+ CalculationType
+ >::type return_type;
 
     typedef Point1 first_point_type;
     typedef Point2 second_point_type;
- typedef cartesian_distance<calculation_type> return_type;
 
- inline return_type apply(Point1 const& p1, Point2 const& p2) const
+ static inline return_type apply(Point1 const& p1, Point2 const& p2)
     {
         BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Point1>) );
         BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Point2>) );
@@ -94,16 +99,209 @@
 
         assert_dimension_equal<Point1, Point2>();
 
- return return_type(detail::compute_pythagoras
+ return detail::compute_pythagoras
             <
                 Point1, Point2,
                 dimension<Point1>::value,
- calculation_type
- >::apply(p1, p2));
+ return_type
+ >::apply(p1, p2);
+ }
+};
+
+} // namespace comparable
+
+
+/*!
+ \brief Strategy for distance point to point: pythagoras
+ \ingroup distance
+ \tparam Point1 first point type
+ \tparam Point2 optional, second point type, defaults to first point type
+ \par Concepts for Point1 and Point2:
+ - specialized point_traits class
+*/
+template
+<
+ typename Point1,
+ typename Point2 = Point1,
+ typename CalculationType = void
+>
+struct pythagoras
+{
+ typedef comparable::pythagoras<Point1, Point2, CalculationType> comparable_type;
+ typedef typename promote_floating_point
+ <
+ typename comparable_type::return_type
+ >::type return_type;
+
+ typedef Point1 first_point_type;
+ typedef Point2 second_point_type;
+
+ static inline return_type apply(Point1 const& p1, Point2 const& p2)
+ {
+ return_type const t = comparable_type::apply(p1, p2);
+ return sqrt(t);
+ }
+};
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+namespace services
+{
+
+template <typename Point1, typename Point2, typename CalculationType>
+struct tag<pythagoras<Point1, Point2, CalculationType> >
+{
+ typedef strategy_tag_distance_point_point type;
+};
+
+
+template
+<
+ typename Point1,
+ typename Point2,
+ typename CalculationType,
+ typename P1,
+ typename P2
+>
+struct similar_type<pythagoras<Point1, Point2, CalculationType>, P1, P2>
+{
+ typedef pythagoras<P1, P2, CalculationType> type;
+};
+
+
+template
+<
+ typename Point1,
+ typename Point2,
+ typename CalculationType,
+ typename P1,
+ typename P2
+>
+struct get_similar<pythagoras<Point1, Point2, CalculationType>, P1, P2>
+{
+ static inline typename similar_type
+ <
+ pythagoras<Point1, Point2, CalculationType>, P1, P2
+ >::type apply(pythagoras<Point1, Point2, CalculationType> const& )
+ {
+ return pythagoras<P1, P2, CalculationType>();
     }
 };
 
 
+template <typename Point1, typename Point2, typename CalculationType>
+struct comparable_type<pythagoras<Point1, Point2, CalculationType> >
+{
+ typedef comparable::pythagoras<Point1, Point2, CalculationType> type;
+};
+
+
+template <typename Point1, typename Point2, typename CalculationType>
+struct get_comparable<pythagoras<Point1, Point2, CalculationType> >
+{
+ typedef comparable::pythagoras<Point1, Point2, CalculationType> comparable_type;
+public :
+ static inline comparable_type apply(pythagoras<Point1, Point2, CalculationType> const& input)
+ {
+ return comparable_type();
+ }
+};
+
+
+template <typename Point1, typename Point2, typename CalculationType>
+struct result_from_distance<pythagoras<Point1, Point2, CalculationType> >
+{
+private :
+ typedef typename pythagoras<Point1, Point2, CalculationType>::return_type return_type;
+public :
+ template <typename T>
+ static inline return_type apply(pythagoras<Point1, Point2, CalculationType> const& , T const& value)
+ {
+ return return_type(value);
+ }
+};
+
+
+// Specializations for comparable::pythagoras
+template <typename Point1, typename Point2, typename CalculationType>
+struct tag<comparable::pythagoras<Point1, Point2, CalculationType> >
+{
+ typedef strategy_tag_distance_point_point type;
+};
+
+
+template
+<
+ typename Point1,
+ typename Point2,
+ typename CalculationType,
+ typename P1,
+ typename P2
+>
+struct similar_type<comparable::pythagoras<Point1, Point2, CalculationType>, P1, P2>
+{
+ typedef comparable::pythagoras<P1, P2, CalculationType> type;
+};
+
+
+template
+<
+ typename Point1,
+ typename Point2,
+ typename CalculationType,
+ typename P1,
+ typename P2
+>
+struct get_similar<comparable::pythagoras<Point1, Point2, CalculationType>, P1, P2>
+{
+ static inline typename similar_type
+ <
+ comparable::pythagoras<Point1, Point2, CalculationType>, P1, P2
+ >::type apply(comparable::pythagoras<Point1, Point2, CalculationType> const& )
+ {
+ return comparable::pythagoras<P1, P2, CalculationType>();
+ }
+};
+
+
+template <typename Point1, typename Point2, typename CalculationType>
+struct comparable_type<comparable::pythagoras<Point1, Point2, CalculationType> >
+{
+ typedef comparable::pythagoras<Point1, Point2, CalculationType> type;
+};
+
+
+template <typename Point1, typename Point2, typename CalculationType>
+struct get_comparable<comparable::pythagoras<Point1, Point2, CalculationType> >
+{
+ typedef comparable::pythagoras<Point1, Point2, CalculationType> comparable_type;
+public :
+ static inline comparable_type apply(comparable::pythagoras<Point1, Point2, CalculationType> const& input)
+ {
+ return comparable_type();
+ }
+};
+
+
+template <typename Point1, typename Point2, typename CalculationType>
+struct result_from_distance<comparable::pythagoras<Point1, Point2, CalculationType> >
+{
+private :
+ typedef typename comparable::pythagoras<Point1, Point2, CalculationType>::return_type return_type;
+public :
+ template <typename T>
+ static inline return_type apply(comparable::pythagoras<Point1, Point2, CalculationType> const& , T const& value)
+ {
+ return_type const v = value;
+ return v * v;
+ }
+};
+
+
+} // namespace services
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
 }} // namespace strategy::distance
 
 
@@ -115,15 +313,20 @@
 };
 
 
-#endif
-
-
 template <typename Point1, typename Point2>
 struct strategy_tag<strategy::distance::pythagoras<Point1, Point2> >
 {
     typedef strategy_tag_distance_point_point type;
 };
 
+template <typename Point1, typename Point2>
+struct strategy_tag<strategy::distance::comparable::pythagoras<Point1, Point2> >
+{
+ typedef strategy_tag_distance_point_point type;
+};
+
+
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
 
 
 }} // namespace boost::geometry

Modified: sandbox/geometry/boost/geometry/strategies/concepts/distance_concept.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/strategies/concepts/distance_concept.hpp (original)
+++ sandbox/geometry/boost/geometry/strategies/concepts/distance_concept.hpp 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -63,10 +63,58 @@
             }
         };
 
+ // 5) must define meta-function "similar_type"
+ typedef typename strategy::distance::services::similar_type
+ <
+ Strategy, ptype2, ptype1
+ >::type stype;
+
+ // 6) must define meta-function "comparable_type"
+ typedef typename strategy::distance::services::comparable_type
+ <
+ Strategy
+ >::type ctype;
+
+ // 6) must define meta-function "tag"
+ typedef typename strategy::distance::services::tag
+ <
+ Strategy
+ >::type tag;
+
+
+ // 7) must define (meta)struct "get_similar" with apply
+ // 8) must define (meta)struct "get_comparable" with apply
+ // 9) must define (meta)struct "result_from_distance" with apply
+ struct services_checker
+ {
+ static void check()
+ {
+ Strategy* str;
+ stype s = strategy::distance::services::get_similar
+ <
+ Strategy,
+ ptype2, ptype1
+ >::apply(*str);
+ ctype c = strategy::distance::services::get_comparable
+ <
+ Strategy
+ >::apply(*str);
+ rtype r = strategy::distance::services::result_from_distance
+ <
+ Strategy
+ >::apply(*str, 1.0);
+
+ boost::ignore_unused_variable_warning(s);
+ boost::ignore_unused_variable_warning(c);
+ }
+ };
+
+
     public :
         BOOST_CONCEPT_USAGE(PointDistanceStrategy)
         {
             apply_checker::check();
+ services_checker::check();
         }
 #endif
 };

Modified: sandbox/geometry/boost/geometry/strategies/distance.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/strategies/distance.hpp (original)
+++ sandbox/geometry/boost/geometry/strategies/distance.hpp 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -10,6 +10,7 @@
 #define BOOST_GEOMETRY_STRATEGIES_DISTANCE_HPP
 
 
+#include <boost/geometry/core/cs.hpp>
 #include <boost/geometry/strategies/tags.hpp>
 
 
@@ -37,9 +38,9 @@
     \tparam CsTag1 tag of coordinate system of point type
     \tparam CsTag2 tag of coordinate system of segment type, usually same as CsTag1
     \tparam Point point-type
- \tparam Segment segment-type
+ \tparam PointOfSegment segment-point-type
 */
-template <typename CsTag1, typename CsTag2, typename Point, typename Segment>
+template <typename CsTag1, typename CsTag2, typename Point, typename PointOfSegment>
 struct strategy_distance_segment
 {
     typedef strategy::not_implemented type;
@@ -47,6 +48,66 @@
 
 
 
+// New functionality:
+template
+<
+ typename Point1,
+ typename Point2 = Point1,
+ typename Tag1 = typename cs_tag<Point1>::type,
+ typename Tag2 = typename cs_tag<Point2>::type
+>
+struct default_distance_strategy
+{
+ typedef typename strategy_distance<Tag1, Tag2, Point1, Point2>::type type;
+};
+
+template
+<
+ typename Point,
+ typename PointOfSegment,
+ typename Tag1 = typename cs_tag<Point>::type,
+ typename Tag2 = typename cs_tag<PointOfSegment>::type
+>
+struct default_distance_strategy_segment
+{
+ typedef typename strategy_distance_segment<Tag1, Tag2, Point, PointOfSegment>::type type;
+};
+
+
+
+namespace strategy { namespace distance { namespace services
+{
+
+template <typename Strategy> struct tag {};
+
+
+/*!
+ \brief Metafunction delivering a similar strategy with other input point types
+*/
+template
+<
+ typename Strategy,
+ typename Point1,
+ typename Point2
+>
+struct similar_type {};
+
+template
+<
+ typename Strategy,
+ typename Point1,
+ typename Point2
+>
+struct get_similar {};
+
+template <typename Strategy> struct comparable_type {};
+template <typename Strategy> struct get_comparable {};
+
+template <typename Strategy> struct result_from_distance {};
+
+
+}}} // namespace strategy::distance::services
+
 
 }} // namespace boost::geometry
 

Modified: sandbox/geometry/boost/geometry/strategies/distance_result.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/strategies/distance_result.hpp (original)
+++ sandbox/geometry/boost/geometry/strategies/distance_result.hpp 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -9,325 +9,35 @@
 #ifndef BOOST_GEOMETRY_STRATEGIES_DISTANCE_RESULT_HPP
 #define BOOST_GEOMETRY_STRATEGIES_DISTANCE_RESULT_HPP
 
-#include <utility>
-#include <cmath>
-#include <limits>
-
-#include <boost/mpl/if.hpp>
-#include <boost/numeric/conversion/cast.hpp>
-#include <boost/type_traits.hpp>
 
 #include <boost/geometry/core/cs.hpp>
 #include <boost/geometry/core/point_type.hpp>
 #include <boost/geometry/strategies/distance.hpp>
-#include <boost/geometry/util/math.hpp>
-#include <boost/geometry/util/select_most_precise.hpp>
 
 
 namespace boost { namespace geometry
 {
 
 /*!
- \brief Encapsulate the results of distance calculation
+ \brief Meta-function defining return type of distance function
     \ingroup distance
- \details Distance calculation for xy points or xyz points is done by taking the square
- root. However, for distance comparison drawing the square root is not necessary.
- Therefore the distance strategies are allowed to return the squares of the distance.
- This structure contains the distance, and a boolean to indicate if it is squared.
- It has an automatic conversion to a double value, which does the square root if necessary.
- \note Thanks to Phil Endecott for his suggestion to change the pair to the double-convertable
- http://article.gmane.org/gmane.comp.lib.boost.devel/172709/match=greatcircle_distance
-*/
-template<typename T = double>
-struct cartesian_distance
-{
- private :
- T m_squared_distance;
-
- // Because result is square-rooted, for integer, the cast should
- // go to double and NOT to T
- typedef typename
- boost::mpl::if_c
- <
- boost::is_integral<T>::type::value,
- double,
- T
- >::type cast_type;
-
-
-
-
- public :
-
-
- /// Constructor with a value
- explicit cartesian_distance(T const& v) : m_squared_distance(v) {}
-
- /// Automatic conversion to double or higher precision,
- /// taking squareroot if necessary
- inline operator cast_type() const
- {
- return boost::numeric_cast<cast_type>
- (
-#if defined(NUMERIC_ADAPTOR_INCLUDED)
- boost::sqrt(
-#else
- std::sqrt(
-#endif
- boost::numeric_cast
- <
- typename select_most_precise<cast_type, double>::type
- >(m_squared_distance)
- )
- );
- }
-
- // Compare squared values
- inline bool operator<(cartesian_distance<T> const& other) const
- {
- return this->m_squared_distance < other.m_squared_distance;
- }
- inline bool operator>(cartesian_distance<T> const& other) const
- {
- return this->m_squared_distance > other.m_squared_distance;
- }
- inline bool operator==(cartesian_distance<T> const& other) const
- {
- return math::equals(this->m_squared_distance, other.m_squared_distance);
- }
-
- // Compare just with a corresponding POD value
- // Note: this is NOT possible because of the cast to double,
- // it makes it for the compiler ambiguous which to take
- /*
- inline bool operator<(T const& value) const
- {
- return this->m_squared_distance < (value * value);
- }
- inline bool operator>(T const& value) const
- {
- return this->m_squared_distance > (value * value);
- }
- inline bool operator==(T const& value) const
- {
- return this->m_squared_distance == (value * value);
- }
- */
-
- // Utility method to compare without SQRT, but not with method above because for epsilon that
- // makes no sense...
- inline bool very_small() const
- {
- return m_squared_distance <= std::numeric_limits<T>::epsilon();
- }
-
- /// The "squared_value" method returns the internal squared value
- inline T squared_value() const
- {
- return m_squared_distance;
- }
-
- /// Make streamable to enable std::cout << geometry::distance( )
- template <typename Char, typename Traits>
- inline friend std::basic_ostream<Char, Traits>&
- operator<<(std::basic_ostream<Char, Traits>& os,
- cartesian_distance<T> const& d)
- {
- // Avoid "ambiguous function call" for MSVC
- cast_type const sq = d.m_squared_distance;
-
- os <<
-#if defined(NUMERIC_ADAPTOR_INCLUDED)
- boost::sqrt(sq);
-#else
- sqrt(sq);
-#endif
- return os;
- }
-
-};
-
-
-
-/*
-
- From Phil Endecott, on the list:
-
- You can go further. If I'm searching through a long list of points to
- find the closest to P then I'll avoid the squaring (and conversion to
- double if my co-ordinates are integers) whenever possible. You can
- achieve this with a more complex distance proxy:
-
- class distance_proxy {
- double dx;
- double dy;
- distance_proxy(double dx_, double dy_): dx(dx_), dy(dy_) {}
- friend pythag_distance(point,point);
- public:
- operator double() { return sqrt(dx*dx+dy*dy); }
- bool operator>(double d) {
- return dx>d
- || dy>d
- || (dx*dx+dy*dy > d*d);
- }
- };
-
- So this is convertible to double, but can be compared to a distance
- without any need for sqrt() and only multiplication in some cases.
- Further refinement is possible.
-
-
- Barend:
- feasable, needs to be templatized by the number of dimensions. For distance it
- results in a nice "delayed calculation".
- For searching you might take another approach, first calculate dx, if OK then dy,
- if OK then the sqrs. So as above but than distance does not need to be calculated.
- So it is in fact another strategy.
-
-
-*/
-
-
-
-#ifndef DOXYGEN_NO_DETAIL
-namespace detail
-{
- namespace distance
- {
- template <typename R, typename T>
- struct distance_result_maker
- {
- };
-
- template <typename R, typename T>
- struct distance_result_maker<geometry::cartesian_distance<R>, T>
- {
- static inline geometry::cartesian_distance<R> apply(T const& value)
- {
- return cartesian_distance<R>(value * value);
- }
- };
-
- template <typename T>
- struct distance_result_maker<double, T>
- {
- static inline double apply(T const& value)
- {
- return value;
- }
- };
-
-
- template <typename T>
- struct close_to_zero
- {
- static inline bool apply(T const& value)
- {
- return value <= std::numeric_limits<T>::epsilon();
- }
- };
-
-
- template <typename T>
- struct close_to_zero<geometry::cartesian_distance<T> >
- {
- static inline bool apply(geometry::cartesian_distance<T> const& value)
- {
- return value.very_small();
- }
- };
-
-
- template <typename T>
- struct fuzzy_equals
- {
- static inline bool apply(T const& left, T const& right)
- {
- return std::abs(left - right) < 0.01;
- }
- };
-
-
- template <typename T>
- struct fuzzy_equals<geometry::cartesian_distance<T> >
- {
- typedef geometry::cartesian_distance<T> D;
- static inline bool apply(D const& left, D const& right)
- {
- return std::abs(left.squared_value() - right.squared_value()) < 1;
- }
- };
-
- }
-}
-#endif
-
+ \note The strategy defines the return-type (so this situation is different
+ from length, where distance is sqr/sqrt, but length always squared)
 
-
-/*!
- \brief Shortcut to define return type of distance strategy
- \ingroup distance
- \tparam Geometry1 first geometry
- \tparam Geometry2 second geometry
  */
-template <typename Geometry1, typename Geometry2 = Geometry1>
+template <typename Geometry1, typename Geometry2>
 struct distance_result
 {
- typedef typename point_type<Geometry1>::type point_type1;
- typedef typename point_type<Geometry2>::type point_type2;
- typedef typename strategy_distance
+ typedef typename default_distance_strategy
         <
- typename cs_tag<point_type1>::type,
- typename cs_tag<point_type2>::type,
- point_type1,
- point_type2
+ typename point_type<Geometry1>::type,
+ typename point_type<Geometry2>::type
>::type strategy_type;
+
     typedef typename strategy_type::return_type type;
 };
 
 
-
-
-
-/*!
- \brief Object generator to create instance which can be compared
- \ingroup distance
- \details If distance results have to be compared to a certain value it makes sense to use
- this function to generate a distance result of a certain value, and compare the distance
- result with this instance. SQRT calculations are then avoided
- \tparam R distance result type
- \tparam T arithmetic type, e.g. double
- \param value the distance to compare with
- \return the distance result
-*/
-template <typename R, typename T>
-inline R make_distance_result(T const& value)
-{
- return detail::distance::distance_result_maker<R, T>::apply(value);
-}
-
-
-/*!
- \brief Utility function to check if a distance is very small
- \ingroup distance
- \details Depending on the "distance result" type it checks if it is smaller than epsilon,
- or (for Cartesian distances) if the square is smaller than epsilon
- \tparam R the distance result type, either arithmetic or cartesian distance
- \param value the distance result to check
-*/
-template <typename T>
-inline bool close_to_zero(T const& value)
-{
- return detail::distance::close_to_zero<T>::apply(value);
-}
-
-template <typename T>
-inline bool fuzzy_equals(T const& left, T const& right)
-{
- return detail::distance::fuzzy_equals<T>::apply(left, right);
-}
-
-
 }} // namespace boost::geometry
 
 

Modified: sandbox/geometry/boost/geometry/strategies/spherical/distance_cross_track.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/strategies/spherical/distance_cross_track.hpp (original)
+++ sandbox/geometry/boost/geometry/strategies/spherical/distance_cross_track.hpp 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -20,11 +20,13 @@
 #include <boost/geometry/strategies/distance.hpp>
 #include <boost/geometry/strategies/concepts/distance_concept.hpp>
 
+#include <boost/geometry/util/promote_floating_point.hpp>
 #include <boost/geometry/util/math.hpp>
 //#include <boost/geometry/util/write_dsv.hpp>
 
 
 
+
 namespace boost { namespace geometry
 {
 
@@ -39,20 +41,30 @@
     \tparam P point type
     \tparam S segment type
 */
-template <typename Point, typename PointOfSegment>
+template
+<
+ typename Point,
+ typename PointOfSegment = Point,
+ typename CalculationType = void,
+ typename Strategy = typename default_distance_strategy<Point>::type
+>
 class cross_track
 {
 public :
- typedef double return_type;
+ typedef typename promote_floating_point
+ <
+ typename select_calculation_type
+ <
+ Point,
+ PointOfSegment,
+ CalculationType
+ >::type
+ >::type return_type;
+
     typedef Point point_type;
     typedef PointOfSegment segment_point_type;
 
- typedef typename strategy_distance
- <
- typename geometry::cs_tag<Point>::type,
- typename geometry::cs_tag<Point>::type,
- Point, Point
- >::type point_strategy_type;
+ typedef Strategy point_strategy_type;
 
     BOOST_CONCEPT_ASSERT
         (
@@ -61,7 +73,7 @@
 
 
 
- inline cross_track(double r = 1.0)
+ inline cross_track(return_type const& r = 1.0)
         : m_radius(r)
         , m_strategy(1.0) // Keep this 1.0 and not r
     {}
@@ -76,14 +88,14 @@
                 PointOfSegment const& sp1, PointOfSegment const& sp2) const
     {
         // http://williams.best.vwh.net/avform.htm#XTE
- double d1 = m_strategy.apply(sp1, p);
+ return_type d1 = m_strategy.apply(sp1, p);
 
         // Actually, calculation of d2 not necessary if we know that the projected point is on the great circle...
- double d2 = m_strategy.apply(sp2, p);
+ return_type d2 = m_strategy.apply(sp2, p);
 
- double crs_AD = course(sp1, p);
- double crs_AB = course(sp1, sp2);
- double XTD = std::abs(asin(sin(d1) * sin(crs_AD - crs_AB)));
+ return_type crs_AD = course(sp1, p);
+ return_type crs_AB = course(sp1, sp2);
+ return_type XTD = abs(asin(sin(d1) * sin(crs_AD - crs_AB)));
 
 //std::cout << "Course " << dsv(sp1) << " to " << dsv(p) << " " << crs_AD * geometry::math::r2d << std::endl;
 //std::cout << "Course " << dsv(sp1) << " to " << dsv(sp2) << " " << crs_AB * geometry::math::r2d << std::endl;
@@ -94,18 +106,20 @@
         return return_type(m_radius * (std::min)((std::min)(d1, d2), XTD));
     }
 
+ inline return_type radius() const { return m_radius; }
+
 private :
- double m_radius;
+ return_type m_radius;
 
     // Point-point distances are calculated in radians, on the unit sphere
     point_strategy_type m_strategy;
 
     /// Calculate course (bearing) between two points. Might be moved to a "course formula" ...
- inline double course(Point const& p1, Point const& p2) const
+ inline return_type course(Point const& p1, Point const& p2) const
     {
         // http://williams.best.vwh.net/avform.htm#Crs
- double dlon = get_as_radian<0>(p2) - get_as_radian<0>(p1);
- double cos_p2lat = cos(get_as_radian<1>(p2));
+ return_type dlon = get_as_radian<0>(p2) - get_as_radian<0>(p1);
+ return_type cos_p2lat = cos(get_as_radian<1>(p2));
 
         // "An alternative formula, not requiring the pre-computation of d"
         return atan2(sin(dlon) * cos_p2lat,
@@ -116,6 +130,91 @@
 };
 
 
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+namespace services
+{
+
+template <typename Point, typename PointOfSegment>
+struct tag<cross_track<Point, PointOfSegment> >
+{
+ typedef strategy_tag_distance_point_segment type;
+};
+
+
+template
+<
+ typename Point,
+ typename PointOfSegment,
+ typename P,
+ typename PS
+>
+struct similar_type<cross_track<Point, PointOfSegment>, P, PS>
+{
+ typedef cross_track<Point, PointOfSegment> type;
+};
+
+
+template
+<
+ typename Point,
+ typename PointOfSegment,
+ typename P,
+ typename PS
+>
+struct get_similar<cross_track<Point, PointOfSegment>, P, PS>
+{
+ static inline typename similar_type
+ <
+ cross_track<Point, PointOfSegment>, P, PS
+ >::type apply(cross_track<Point, PointOfSegment> const& strategy)
+ {
+ return cross_track<P, PS>(strategy.radius());
+ }
+};
+
+
+template <typename Point, typename PointOfSegment>
+struct comparable_type<cross_track<Point, PointOfSegment> >
+{
+ // Comparable type is here just the strategy
+ typedef typename similar_type<cross_track<Point, PointOfSegment>, Point, PointOfSegment>::type type;
+};
+
+
+template <typename Point, typename PointOfSegment>
+struct get_comparable<cross_track<Point, PointOfSegment> >
+{
+ typedef typename comparable_type
+ <
+ cross_track<Point, PointOfSegment>
+ >::type comparable_type;
+public :
+ static inline comparable_type apply(cross_track<Point, PointOfSegment> const& strategy)
+ {
+ return comparable_type(strategy.radius());
+ }
+};
+
+
+template <typename Point, typename PointOfSegment>
+struct result_from_distance<cross_track<Point, PointOfSegment> >
+{
+private :
+ typedef typename cross_track<Point, PointOfSegment>::return_type return_type;
+public :
+ template <typename T>
+ static inline return_type apply(cross_track<Point, PointOfSegment> const& , T const& distance)
+ {
+ return distance;
+ }
+};
+
+
+} // namespace services
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
 }} // namespace strategy::distance
 
 
@@ -131,10 +230,10 @@
 
 
 // Use this point-segment for geographic as well. TODO: change this, extension!
-template <typename Point, typename Segment>
-struct strategy_distance_segment<geographic_tag, geographic_tag, Point, Segment>
+template <typename Point, typename PointOfSegment>
+struct strategy_distance_segment<geographic_tag, geographic_tag, Point, PointOfSegment>
 {
- typedef strategy::distance::cross_track<Point, Segment> type;
+ typedef strategy::distance::cross_track<Point, PointOfSegment> type;
 };
 
 
@@ -145,14 +244,9 @@
 };
 
 
-
 #endif
 
 
-
-
-
-
 }} // namespace boost::geometry
 
 

Modified: sandbox/geometry/boost/geometry/strategies/spherical/distance_haversine.hpp
==============================================================================
--- sandbox/geometry/boost/geometry/strategies/spherical/distance_haversine.hpp (original)
+++ sandbox/geometry/boost/geometry/strategies/spherical/distance_haversine.hpp 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -14,6 +14,8 @@
 #include <boost/geometry/core/access.hpp>
 #include <boost/geometry/core/radian_access.hpp>
 
+#include <boost/geometry/util/select_calculation_type.hpp>
+#include <boost/geometry/util/promote_floating_point.hpp>
 
 #include <boost/geometry/strategies/distance.hpp>
 
@@ -23,9 +25,77 @@
 namespace boost { namespace geometry
 {
 
+
 namespace strategy { namespace distance
 {
 
+
+namespace comparable
+{
+
+// Comparable haversine.
+// To compare distances, we can avoid:
+// - multiplication with radius and 2.0
+// - applying sqrt
+// - applying asin (which is strictly (monotone) increasing)
+template
+<
+ typename Point1,
+ typename Point2 = Point1,
+ typename CalculationType = void
+>
+class haversine
+{
+public :
+ typedef typename promote_floating_point
+ <
+ typename select_calculation_type
+ <
+ Point1,
+ Point2,
+ CalculationType
+ >::type
+ >::type return_type;
+
+ typedef Point1 first_point_type;
+ typedef Point2 second_point_type;
+
+ inline haversine(return_type const& r = 1.0)
+ : m_radius(r)
+ {}
+
+
+ static inline return_type apply(Point1 const& p1, Point2 const& p2)
+ {
+ return calculate(get_as_radian<0>(p1), get_as_radian<1>(p1),
+ get_as_radian<0>(p2), get_as_radian<1>(p2));
+ }
+
+ inline return_type radius() const
+ {
+ return m_radius;
+ }
+
+
+private :
+ typedef return_type promoted_type;
+
+ static inline return_type calculate(promoted_type const& lon1,
+ promoted_type const& lat1,
+ promoted_type const& lon2,
+ promoted_type const& lat2)
+ {
+ return math::hav(lat2 - lat1)
+ + cos(lat1) * cos(lat2) * math::hav(lon2 - lon1);
+ }
+
+ return_type m_radius;
+};
+
+
+
+} // namespace comparable
+
 /*!
     \brief Distance calculation for spherical coordinates
         on a perfect sphere using haversine
@@ -43,71 +113,200 @@
                 + cos(lat1)*cos(lat2)*(sin((lon1-lon2)/2))^2))
                 </em>
 */
-template <typename Point1, typename Point2 = Point1>
+template
+<
+ typename Point1,
+ typename Point2 = Point1,
+ typename CalculationType = void
+>
 class haversine
 {
+ typedef comparable::haversine<Point1, Point2, CalculationType> comparable_type;
+
 public :
     typedef Point1 first_point_type;
     typedef Point2 second_point_type;
- typedef double return_type;
 
- inline haversine(double r = 1.0)
+ typedef typename comparable_type::return_type return_type;
+
+ inline haversine(return_type const& r = 1.0)
         : m_radius(r)
     {}
 
     inline return_type apply(Point1 const& p1, Point2 const& p2) const
     {
- return calculate(get_as_radian<0>(p1), get_as_radian<1>(p1),
- get_as_radian<0>(p2), get_as_radian<1>(p2));
+ return_type const a = comparable_type::apply(p1, p2);
+ return_type const c = return_type(2.0) * asin(sqrt(a));
+ return m_radius * c;
     }
 
-private :
- double m_radius;
- typedef typename coordinate_type<Point1>::type coordinate_type1;
- typedef typename coordinate_type<Point2>::type coordinate_type2;
-
- inline return_type calculate(coordinate_type1 const& lon1,
- coordinate_type1 const& lat1,
- coordinate_type2 const& lon2,
- coordinate_type2 const& lat2) const
+ inline return_type radius() const
     {
- double a = math::hav(lat2 - lat1)
- + cos(lat1) * cos(lat2) * math::hav(lon2 - lon1);
- double c = 2.0 * asin(sqrt(a));
- return return_type(m_radius * c);
+ return m_radius;
     }
+
+private :
+ return_type m_radius;
 };
 
 
-}} // namespace strategy::distance
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+namespace services
+{
 
+template <typename Point1, typename Point2, typename CalculationType>
+struct tag<haversine<Point1, Point2, CalculationType> >
+{
+ typedef strategy_tag_distance_point_point type;
+};
 
-#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
-template <typename P1, typename P2>
-struct strategy_distance<spherical_tag, spherical_tag, P1, P2>
+
+template <typename Point1, typename Point2, typename CalculationType, typename P1, typename P2>
+struct similar_type<haversine<Point1, Point2, CalculationType>, P1, P2>
+{
+ typedef haversine<P1, P2, CalculationType> type;
+};
+
+
+template <typename Point1, typename Point2, typename CalculationType, typename P1, typename P2>
+struct get_similar<haversine<Point1, Point2, CalculationType>, P1, P2>
+{
+private :
+ typedef haversine<Point1, Point2, CalculationType> this_type;
+public :
+ static inline typename similar_type<this_type, P1, P2>::type apply(this_type const& input)
+ {
+ return haversine<P1, P2, CalculationType>(input.radius());
+ }
+};
+
+template <typename Point1, typename Point2, typename CalculationType>
+struct comparable_type<haversine<Point1, Point2, CalculationType> >
 {
- typedef strategy::distance::haversine<P1, P2> type;
+ typedef comparable::haversine<Point1, Point2, CalculationType> type;
 };
 
 
+template <typename Point1, typename Point2, typename CalculationType>
+struct get_comparable<haversine<Point1, Point2, CalculationType> >
+{
+private :
+ typedef haversine<Point1, Point2, CalculationType> this_type;
+ typedef comparable::haversine<Point1, Point2, CalculationType> comparable_type;
+public :
+ static inline comparable_type apply(this_type const& input)
+ {
+ return comparable_type(input.radius());
+ }
+};
 
+template <typename Point1, typename Point2, typename CalculationType>
+struct result_from_distance<haversine<Point1, Point2, CalculationType> >
+{
+private :
+ typedef haversine<Point1, Point2, CalculationType> this_type;
+public :
+ template <typename T>
+ static inline typename this_type::return_type apply(this_type const& , T const& value)
+ {
+ return typename this_type::return_type(value);
+ }
+};
 
 
 
-template <typename P1, typename P2>
-struct strategy_tag<strategy::distance::haversine<P1, P2> >
+// Specializations for comparable::haversine
+template <typename Point1, typename Point2, typename CalculationType>
+struct tag<comparable::haversine<Point1, Point2, CalculationType> >
 {
     typedef strategy_tag_distance_point_point type;
 };
 
 
+template <typename Point1, typename Point2, typename CalculationType, typename P1, typename P2>
+struct similar_type<comparable::haversine<Point1, Point2, CalculationType>, P1, P2>
+{
+ typedef comparable::haversine<P1, P2, CalculationType> type;
+};
 
 
-#endif
+template <typename Point1, typename Point2, typename CalculationType, typename P1, typename P2>
+struct get_similar<comparable::haversine<Point1, Point2, CalculationType>, P1, P2>
+{
+private :
+ typedef comparable::haversine<Point1, Point2, CalculationType> this_type;
+public :
+ static inline typename similar_type<this_type, P1, P2>::type apply(this_type const& input)
+ {
+ return comparable::haversine<P1, P2, CalculationType>(input.radius());
+ }
+};
 
+template <typename Point1, typename Point2, typename CalculationType>
+struct comparable_type<comparable::haversine<Point1, Point2, CalculationType> >
+{
+ typedef comparable::haversine<Point1, Point2, CalculationType> type;
+};
 
 
+template <typename Point1, typename Point2, typename CalculationType>
+struct get_comparable<comparable::haversine<Point1, Point2, CalculationType> >
+{
+private :
+ typedef comparable::haversine<Point1, Point2, CalculationType> this_type;
+public :
+ static inline this_type apply(this_type const& input)
+ {
+ return input;
+ }
+};
+
+
+template <typename Point1, typename Point2, typename CalculationType>
+struct result_from_distance<comparable::haversine<Point1, Point2, CalculationType> >
+{
+private :
+ typedef comparable::haversine<Point1, Point2, CalculationType> strategy_type;
+ typedef typename strategy_type::return_type return_type;
+public :
+ template <typename T>
+ static inline return_type apply(strategy_type const& strategy, T const& distance)
+ {
+ return_type const s = sin((distance / strategy.radius()) / return_type(2));
+ return s * s;
+ }
+};
+
+
+} // namespace services
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+
+
+}} // namespace strategy::distance
+
+
+#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
+template <typename Point1, typename Point2>
+struct strategy_distance<spherical_tag, spherical_tag, Point1, Point2>
+{
+ typedef strategy::distance::haversine<Point1, Point2> type;
+};
+
+
+template <typename Point1, typename Point2>
+struct strategy_tag<strategy::distance::haversine<Point1, Point2> >
+{
+ typedef strategy_tag_distance_point_point type;
+};
+
+template <typename Point1, typename Point2>
+struct strategy_tag<strategy::distance::comparable::haversine<Point1, Point2> >
+{
+ typedef strategy_tag_distance_point_point type;
+};
+
 
+#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
 
 
 }} // namespace boost::geometry

Added: sandbox/geometry/boost/geometry/util/promote_floating_point.hpp
==============================================================================
--- (empty file)
+++ sandbox/geometry/boost/geometry/util/promote_floating_point.hpp 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -0,0 +1,44 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+//
+// Copyright Barend Gehrels 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_PROMOTE_FLOATING_POINT_HPP
+#define BOOST_GEOMETRY_UTIL_PROMOTE_FLOATING_POINT_HPP
+
+
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+
+/*!
+ \brief Meta-function converting, if necessary, to "a floating point" type
+ \details
+ - if input type is integer, type is double
+ - else type is input type
+ \ingroup utility
+ */
+
+template <typename T, typename PromoteIntegerTo = double>
+struct promote_floating_point
+{
+ typedef typename
+ boost::mpl::if_
+ <
+ boost::is_integral<T>,
+ PromoteIntegerTo,
+ T
+ >::type type;
+};
+
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_UTIL_PROMOTE_FLOATING_POINT_HPP

Modified: sandbox/geometry/libs/geometry/example/c01_custom_point_example.cpp
==============================================================================
--- sandbox/geometry/libs/geometry/example/c01_custom_point_example.cpp (original)
+++ sandbox/geometry/libs/geometry/example/c01_custom_point_example.cpp 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -70,6 +70,17 @@
     double m_x, m_y;
 };
 
+// Sample point within a namespace
+namespace my
+{
+ struct my_namespaced_point
+ {
+ double x, y;
+ };
+}
+
+
+
 BOOST_GEOMETRY_REGISTER_POINT_3D(my_color_point, double, cs::cartesian, red, green, blue)
 BOOST_GEOMETRY_REGISTER_POINT_3D(my_array_point, int, cs::cartesian, c[0], c[1], c[2])
 BOOST_GEOMETRY_REGISTER_POINT_2D(my_2d, float, cs::cartesian, x, y)
@@ -77,6 +88,9 @@
 BOOST_GEOMETRY_REGISTER_POINT_2D(my_class_rw, double, cs::cartesian, x(), y())
 BOOST_GEOMETRY_REGISTER_POINT_2D_GET_SET(my_class_gs, double, cs::cartesian, get_x, get_y, set_x, set_y)
 
+BOOST_GEOMETRY_REGISTER_POINT_2D(my::my_namespaced_point, double, cs::cartesian, x, y)
+
+
 int main()
 {
     // Create 2 instances of our custom color point
@@ -132,5 +146,13 @@
         << boost::geometry::dsv(crw2) << " is "
         << boost::geometry::distance(cgs1,cgs2) << std::endl;
 
+ my::my_namespaced_point nsp1 = boost::geometry::make<my::my_namespaced_point>(1, 2);
+ my::my_namespaced_point nsp2 = boost::geometry::make<my::my_namespaced_point>(3, 4);
+ std::cout << "namespaced distance "
+ << boost::geometry::dsv(nsp1) << " to "
+ << boost::geometry::dsv(nsp2) << " is "
+ << boost::geometry::distance(nsp1,nsp2) << std::endl;
+
+
     return 0;
 }

Modified: sandbox/geometry/libs/geometry/test/algorithms/algorithms_tests.sln
==============================================================================
--- sandbox/geometry/libs/geometry/test/algorithms/algorithms_tests.sln (original)
+++ sandbox/geometry/libs/geometry/test/algorithms/algorithms_tests.sln 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -58,6 +58,8 @@
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dissolve", "dissolve.vcproj", "{206F83D5-17F9-4856-A1DE-82301DB94439}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "comparable_distance", "comparable_distance.vcproj", "{F11970B5-BE16-4FF5-9780-4C15082B76A0}"
+EndProject
 Global
         GlobalSection(SolutionConfigurationPlatforms) = preSolution
                 Debug|Win32 = Debug|Win32
@@ -180,6 +182,10 @@
                 {206F83D5-17F9-4856-A1DE-82301DB94439}.Debug|Win32.Build.0 = Debug|Win32
                 {206F83D5-17F9-4856-A1DE-82301DB94439}.Release|Win32.ActiveCfg = Release|Win32
                 {206F83D5-17F9-4856-A1DE-82301DB94439}.Release|Win32.Build.0 = Release|Win32
+ {F11970B5-BE16-4FF5-9780-4C15082B76A0}.Debug|Win32.ActiveCfg = Debug|Win32
+ {F11970B5-BE16-4FF5-9780-4C15082B76A0}.Debug|Win32.Build.0 = Debug|Win32
+ {F11970B5-BE16-4FF5-9780-4C15082B76A0}.Release|Win32.ActiveCfg = Release|Win32
+ {F11970B5-BE16-4FF5-9780-4C15082B76A0}.Release|Win32.Build.0 = Release|Win32
         EndGlobalSection
         GlobalSection(SolutionProperties) = preSolution
                 HideSolutionNode = FALSE

Added: sandbox/geometry/libs/geometry/test/algorithms/comparable_distance.cpp
==============================================================================
--- (empty file)
+++ sandbox/geometry/libs/geometry/test/algorithms/comparable_distance.cpp 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -0,0 +1,138 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library) test file
+//
+// Copyright Barend Gehrels 2007-2009, Geodan, Amsterdam, the Netherlands
+// Copyright Bruno Lalande 2008, 2009
+// 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)
+
+
+#include <sstream>
+
+#include <boost/mpl/if.hpp>
+#include <geometry_test_common.hpp>
+
+#include <boost/geometry/geometry.hpp>
+
+#include <boost/geometry/geometries/point_xy.hpp>
+#include <boost/geometry/geometries/linestring.hpp>
+
+#include <boost/geometry/algorithms/comparable_distance.hpp>
+#include <boost/geometry/strategies/strategies.hpp>
+
+
+#include <boost/geometry/geometries/geometries.hpp>
+
+namespace bg = boost::geometry;
+
+template <typename P>
+void test_distance_result()
+{
+ typedef typename bg::distance_result<P, P>::type distance_type;
+
+ P p1 = bg::make<P>(0, 0);
+ P p2 = bg::make<P>(3, 0);
+ P p3 = bg::make<P>(0, 4);
+
+ distance_type dr12 = bg::comparable_distance(p1, p2);
+ distance_type dr13 = bg::comparable_distance(p1, p3);
+ distance_type dr23 = bg::comparable_distance(p2, p3);
+
+ BOOST_CHECK_CLOSE(double(dr12), 9.000, 0.001);
+ BOOST_CHECK_CLOSE(double(dr13), 16.000, 0.001);
+ BOOST_CHECK_CLOSE(double(dr23), 25.000, 0.001);
+
+}
+
+template <typename P>
+void test_distance_point()
+{
+ P p1;
+ bg::set<0>(p1, 1);
+ bg::set<1>(p1, 1);
+
+ P p2;
+ bg::set<0>(p2, 2);
+ bg::set<1>(p2, 2);
+
+ double d = bg::comparable_distance(p1, p2);
+ BOOST_CHECK_CLOSE(d, 2.0, 0.001);
+}
+
+template <typename P>
+void test_distance_segment()
+{
+ typedef typename bg::coordinate_type<P>::type coordinate_type;
+
+ P s1 = bg::make<P>(2, 2);
+ P s2 = bg::make<P>(3, 3);
+
+ // Check points left, right, projected-left, projected-right, on segment
+ P p1 = bg::make<P>(0, 0);
+ P p2 = bg::make<P>(4, 4);
+ P p3 = bg::make<P>(2.4, 2.6);
+ P p4 = bg::make<P>(2.6, 2.4);
+ P p5 = bg::make<P>(2.5, 2.5);
+
+ bg::segment<P const> const seg(s1, s2);
+
+ double d1 = bg::comparable_distance(p1, seg); BOOST_CHECK_CLOSE(d1, 2.0, 0.001);
+ double d2 = bg::comparable_distance(p2, seg); BOOST_CHECK_CLOSE(d2, 1.0, 0.001);
+ double d3 = bg::comparable_distance(p3, seg); BOOST_CHECK_CLOSE(d3, 0.02, 0.001);
+ double d4 = bg::comparable_distance(p4, seg); BOOST_CHECK_CLOSE(d4, 0.02, 0.001);
+ double d5 = bg::comparable_distance(p5, seg); BOOST_CHECK_CLOSE(d5, 0.0, 0.001);
+
+ // Reverse case
+ double dr1 = bg::comparable_distance(seg, p1); BOOST_CHECK_CLOSE(dr1, d1, 0.001);
+ double dr2 = bg::comparable_distance(seg, p2); BOOST_CHECK_CLOSE(dr2, d2, 0.001);
+}
+
+template <typename P>
+void test_distance_linestring()
+{
+ bg::linestring<P> points;
+ points.push_back(bg::make<P>(1, 1));
+ points.push_back(bg::make<P>(3, 3));
+
+ P p = bg::make<P>(2, 1);
+
+ double d = bg::comparable_distance(p, points);
+ BOOST_CHECK_CLOSE(d, 0.70710678, 0.001);
+
+ p = bg::make<P>(5, 5);
+ d = bg::comparable_distance(p, points);
+ BOOST_CHECK_CLOSE(d, 2.828427, 0.001);
+
+
+ bg::linestring<P> line;
+ line.push_back(bg::make<P>(1,1));
+ line.push_back(bg::make<P>(2,2));
+ line.push_back(bg::make<P>(3,3));
+
+ p = bg::make<P>(5, 5);
+
+ d = bg::comparable_distance(p, line);
+ BOOST_CHECK_CLOSE(d, 2.828427, 0.001);
+
+ // Reverse case
+ d = bg::comparable_distance(line, p);
+ BOOST_CHECK_CLOSE(d, 2.828427, 0.001);
+}
+
+template <typename P>
+void test_all()
+{
+ test_distance_result<P>();
+ test_distance_point<P>();
+ test_distance_segment<P>();
+ test_distance_linestring<P>();
+}
+
+int test_main(int, char* [])
+{
+ //test_all<bg::point_xy<int> >();
+ test_all<bg::point_xy<float> >();
+ test_all<bg::point_xy<double> >();
+
+ return 0;
+}

Added: sandbox/geometry/libs/geometry/test/algorithms/comparable_distance.vcproj
==============================================================================
--- (empty file)
+++ sandbox/geometry/libs/geometry/test/algorithms/comparable_distance.vcproj 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -0,0 +1,174 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="comparable_distance"
+ ProjectGUID="{F11970B5-BE16-4FF5-9780-4C15082B76A0}"
+ RootNamespace="comparable_distance"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\comparable_distance"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\boost.vsprops"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../../..;.."
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ ExceptionHandling="2"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ DebugInformationFormat="1"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)\comparable_distance"
+ ConfigurationType="1"
+ InheritedPropertySheets="..\boost.vsprops"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="../../../..;.."
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ ExceptionHandling="2"
+ UsePrecompiledHeader="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <File
+ RelativePath=".\comparable_distance.cpp"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>

Modified: sandbox/geometry/libs/geometry/test/algorithms/distance.cpp
==============================================================================
--- sandbox/geometry/libs/geometry/test/algorithms/distance.cpp (original)
+++ sandbox/geometry/libs/geometry/test/algorithms/distance.cpp 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -52,26 +52,34 @@
     BOOST_CHECK_CLOSE(double(dr13), 4.000, 0.001);
     BOOST_CHECK_CLOSE(double(dr23), 5.000, 0.001);
 
- // COMPILATION TESTS
- distance_type comparable = boost::geometry::make_distance_result<distance_type>(3);
- //BOOST_CHECK_CLOSE(comparable.value(), 9.000, 0.001);
-
-
- // Question: how to check if the implemented operator is used, and not the auto-conversion to double?
- if (comparable == dr12) {};
- if (comparable < dr12) {};
- if (comparable > dr12) {};
-
- // Check streamability
- std::ostringstream s;
- s << comparable;
-
- // Check comparisons with plain double
- double d = 3.0;
- if (dr12 == d) {};
- if (dr12 < d) {};
- if (dr12 > d) {};
+ // COMPARABLE TESTS
+ {
+ namespace services = boost::geometry::strategy::distance::services;
+
+ typedef typename boost::geometry::default_distance_strategy<P>::type strategy_type;
+ typedef typename services::comparable_type<strategy_type>::type comparable_strategy_type;
 
+ strategy_type strategy;
+ comparable_strategy_type comparable_strategy = services::get_comparable<strategy_type>::apply(strategy);
+ distance_type comparable = services::result_from_distance<comparable_strategy_type>::apply(comparable_strategy, 3);
+
+ BOOST_CHECK_CLOSE(comparable, 9.000, 0.001);
+
+ // COMPILATION TESTS (probably obsolete...)
+ if (comparable == dr12) {};
+ if (comparable < dr12) {};
+ if (comparable > dr12) {};
+
+ // Check streamability
+ std::ostringstream s;
+ s << comparable;
+
+ // Check comparisons with plain double
+ double d = 3.0;
+ if (dr12 == d) {};
+ if (dr12 < d) {};
+ if (dr12 > d) {};
+ }
 }
 
 template <typename P>
@@ -180,22 +188,22 @@
 {
     test_distance_result<P>();
     test_distance_point<P>();
- test_distance_segment<P>();
+// test_distance_segment<P>();
 #ifndef TEST_ARRAY
- test_distance_linestring<P>();
+ //test_distance_linestring<P>();
 #endif
 }
 
 int test_main(int, char* [])
 {
 #ifdef TEST_ARRAY
- //test_all<int[2]>();
+ test_all<int[2]>();
     test_all<float[2]>();
     test_all<double[2]>();
     test_all<test::test_point>(); // located here because of 3D
 #endif
 
- //test_all<boost::geometry::point_xy<int> >();
+ test_all<boost::geometry::point_xy<int> >();
     test_all<boost::tuple<float, float> >();
     test_all<boost::geometry::point_xy<float> >();
     test_all<boost::geometry::point_xy<double> >();

Modified: sandbox/geometry/libs/geometry/test/algorithms/intersection.cpp
==============================================================================
--- sandbox/geometry/libs/geometry/test/algorithms/intersection.cpp (original)
+++ sandbox/geometry/libs/geometry/test/algorithms/intersection.cpp 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -29,6 +29,11 @@
 
     std::string clip = "box(2 2,8 8)";
 
+ test_one<polygon, polygon, polygon>("simplex_normal",
+ simplex_normal[0], simplex_normal[1],
+ 1, 7, 5.47363293);
+
+
     // Basic check: box/linestring, is clipping OK? should compile in any order
     test_one<linestring, linestring, box>("llb", "LINESTRING(0 0,10 10)", clip, 1, 2, sqrt(2.0 * 6.0 * 6.0));
     test_one<linestring, box, linestring>("lbl", clip, "LINESTRING(0 0,10 10)", 1, 2, sqrt(2.0 * 6.0 * 6.0));

Modified: sandbox/geometry/libs/geometry/test/algorithms/overlaps.cpp
==============================================================================
--- sandbox/geometry/libs/geometry/test/algorithms/overlaps.cpp (original)
+++ sandbox/geometry/libs/geometry/test/algorithms/overlaps.cpp 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -20,6 +20,10 @@
 template <typename P>
 void test_2d()
 {
+#if defined(BOOST_GEOMETRY_COMPILE_FAIL)
+ test_geometry<P, P>("POINT(1 1)", "POINT(1 1)", true);
+#endif
+
     test_geometry<boost::geometry::box<P>, boost::geometry::box<P> >("BOX(1 1, 3 3)", "BOX(0 0,2 2)", true);
 
     // touch -> false

Modified: sandbox/geometry/libs/geometry/test/algorithms/simplify.cpp
==============================================================================
--- sandbox/geometry/libs/geometry/test/algorithms/simplify.cpp (original)
+++ sandbox/geometry/libs/geometry/test/algorithms/simplify.cpp 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -77,7 +77,7 @@
 {
     // Integer compiles, but simplify-process fails (due to distances)
     //test_all<boost::geometry::point_xy<int> >();
- //test_all<boost::geometry::point_xy<float> >();
+ test_all<boost::geometry::point_xy<float> >();
     test_all<boost::geometry::point_xy<double> >();
 
     test_spherical<boost::geometry::point<double, 2, boost::geometry::cs::spherical<boost::geometry::degree> > >();

Modified: sandbox/geometry/libs/geometry/test/algorithms/simplify.vcproj
==============================================================================
--- sandbox/geometry/libs/geometry/test/algorithms/simplify.vcproj (original)
+++ sandbox/geometry/libs/geometry/test/algorithms/simplify.vcproj 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -6,7 +6,6 @@
         ProjectGUID="{B1760CB8-553B-42AB-B54E-3D0320FF252F}"
         RootNamespace="simplify"
         Keyword="Win32Proj"
- TargetFrameworkVersion="131072"
>
         <Platforms>
                 <Platform
@@ -44,8 +43,8 @@
                                 Optimization="0"
                                 AdditionalIncludeDirectories="../../../..;.."
                                 PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
- RuntimeLibrary="1"
                                 ExceptionHandling="2"
+ RuntimeLibrary="1"
                                 UsePrecompiledHeader="0"
                                 DebugInformationFormat="1"
                         />
@@ -83,6 +82,9 @@
                                 Name="VCAppVerifierTool"
                         />
                         <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
                                 Name="VCPostBuildEventTool"
                         />
                 </Configuration>
@@ -152,6 +154,9 @@
                                 Name="VCAppVerifierTool"
                         />
                         <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
                                 Name="VCPostBuildEventTool"
                         />
                 </Configuration>

Modified: sandbox/geometry/libs/geometry/test/extensions/gis/latlong/andoyer.cpp
==============================================================================
--- sandbox/geometry/libs/geometry/test/extensions/gis/latlong/andoyer.cpp (original)
+++ sandbox/geometry/libs/geometry/test/extensions/gis/latlong/andoyer.cpp 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -9,6 +9,8 @@
 
 #include <geometry_test_common.hpp>
 
+#include <boost/concept_check.hpp>
+
 #include <boost/geometry/extensions/gis/geographic/strategies/andoyer.hpp>
 
 #include <boost/geometry/strategies/strategies.hpp>
@@ -20,7 +22,12 @@
 template <typename P1, typename P2>
 void test_andoyer(double lon1, double lat1, double lon2, double lat2, double expected_km)
 {
- boost::geometry::strategy::distance::andoyer<P1, P2> andoyer;
+ typedef boost::geometry::strategy::distance::andoyer<P1, P2> andoyer_type;
+
+ BOOST_CONCEPT_ASSERT( (boost::geometry::concept::PointDistanceStrategy<andoyer_type>) );
+
+ andoyer_type andoyer;
+
 
     P1 p1, p2;
 

Modified: sandbox/geometry/libs/geometry/test/extensions/gis/latlong/latlong.sln
==============================================================================
--- sandbox/geometry/libs/geometry/test/extensions/gis/latlong/latlong.sln (original)
+++ sandbox/geometry/libs/geometry/test/extensions/gis/latlong/latlong.sln 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -13,6 +13,8 @@
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "parse", "parse.vcproj", "{38C7173B-F81D-427D-B236-57611A31656A}"
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vincenty", "vincenty.vcproj", "{F4A5BE68-7213-498D-944B-023B50FB10FD}"
+EndProject
 Global
         GlobalSection(SolutionConfigurationPlatforms) = preSolution
                 Debug|Win32 = Debug|Win32
@@ -43,6 +45,10 @@
                 {38C7173B-F81D-427D-B236-57611A31656A}.Debug|Win32.Build.0 = Debug|Win32
                 {38C7173B-F81D-427D-B236-57611A31656A}.Release|Win32.ActiveCfg = Release|Win32
                 {38C7173B-F81D-427D-B236-57611A31656A}.Release|Win32.Build.0 = Release|Win32
+ {F4A5BE68-7213-498D-944B-023B50FB10FD}.Debug|Win32.ActiveCfg = Debug|Win32
+ {F4A5BE68-7213-498D-944B-023B50FB10FD}.Debug|Win32.Build.0 = Debug|Win32
+ {F4A5BE68-7213-498D-944B-023B50FB10FD}.Release|Win32.ActiveCfg = Release|Win32
+ {F4A5BE68-7213-498D-944B-023B50FB10FD}.Release|Win32.Build.0 = Release|Win32
         EndGlobalSection
         GlobalSection(SolutionProperties) = preSolution
                 HideSolutionNode = FALSE

Modified: sandbox/geometry/libs/geometry/test/strategies/cross_track.cpp
==============================================================================
--- sandbox/geometry/libs/geometry/test/strategies/cross_track.cpp (original)
+++ sandbox/geometry/libs/geometry/test/strategies/cross_track.cpp 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -9,6 +9,7 @@
 
 #include <geometry_test_common.hpp>
 
+
 #include <boost/geometry/algorithms/assign.hpp>
 
 #include <boost/geometry/strategies/spherical/distance_haversine.hpp>
@@ -19,6 +20,10 @@
 #include <boost/geometry/geometries/point.hpp>
 #include <boost/geometry/geometries/segment.hpp>
 
+#ifdef HAVE_TTMATH
+# include <boost/geometry/extensions/contrib/ttmath_stub.hpp>
+#endif
+
 
 template <typename Point>
 void test_distance(double lon1, double lat1,
@@ -31,6 +36,8 @@
             Point,
             Point
> strategy_type;
+ typedef typename strategy_type::return_type return_type;
+
 
 
     BOOST_CONCEPT_ASSERT
@@ -45,9 +52,9 @@
     boost::geometry::assign(p1, lon1, lat1);
     boost::geometry::assign(p2, lon2, lat2);
     boost::geometry::assign(p3, lon3, lat3);
- typename strategy_type::return_type d = strategy.apply(p1, p2, p3);
+ return_type d = strategy.apply(p1, p2, p3);
 
- BOOST_CHECK_CLOSE((double) d, expected, tolerance);
+ BOOST_CHECK_CLOSE(d, return_type(expected), tolerance);
 }
 
 template <typename Point>
@@ -63,9 +70,17 @@
     test_distance<Point>(2, 48, 2, 41, 4, 52, average_earth_radius, p_to_ab, 1.0);
 }
 
+
 int test_main(int, char* [])
 {
     test_all<boost::geometry::point<double, 2, boost::geometry::cs::spherical<boost::geometry::degree> > >();
 
+#if defined(HAVE_TTMATH)
+ typedef ttmath::Big<1,4> tt;
+ test_all<boost::geometry::point<tt, 2, boost::geometry::cs::spherical<boost::geometry::degree> > >();
+#endif
+
+
+
     return 0;
 }

Modified: sandbox/geometry/libs/geometry/test/strategies/cross_track.vcproj
==============================================================================
--- sandbox/geometry/libs/geometry/test/strategies/cross_track.vcproj (original)
+++ sandbox/geometry/libs/geometry/test/strategies/cross_track.vcproj 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -20,7 +20,7 @@
                         OutputDirectory="$(SolutionDir)$(ConfigurationName)"
                         IntermediateDirectory="$(ConfigurationName)\cross_track"
                         ConfigurationType="1"
- InheritedPropertySheets="..\boost.vsprops"
+ InheritedPropertySheets="..\boost.vsprops;..\ttmath.vsprops"
                         CharacterSet="1"
>
                         <Tool
@@ -93,7 +93,7 @@
                         OutputDirectory="$(SolutionDir)$(ConfigurationName)"
                         IntermediateDirectory="$(ConfigurationName)\cross_track"
                         ConfigurationType="1"
- InheritedPropertySheets="..\boost.vsprops"
+ InheritedPropertySheets="..\boost.vsprops;..\ttmath.vsprops"
                         CharacterSet="1"
                         WholeProgramOptimization="1"
>

Modified: sandbox/geometry/libs/geometry/test/strategies/haversine.cpp
==============================================================================
--- sandbox/geometry/libs/geometry/test/strategies/haversine.cpp (original)
+++ sandbox/geometry/libs/geometry/test/strategies/haversine.cpp 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -19,47 +19,59 @@
 
 #include <boost/geometry/geometries/point.hpp>
 
+#ifdef HAVE_TTMATH
+# include <boost/geometry/extensions/contrib/ttmath_stub.hpp>
+#endif
+
+namespace bg = boost::geometry;
+
+
+double const average_earth_radius = 6372795.0;
+
 
 template <typename Point>
 struct test_distance
 {
- typedef boost::geometry::strategy::distance::haversine
+ typedef bg::strategy::distance::haversine
         <
             Point,
             Point
> haversine_type;
 
+ BOOST_CONCEPT_ASSERT( (boost::geometry::concept::PointDistanceStrategy<haversine_type>) );
+
+
+ typedef typename haversine_type::return_type return_type;
 
     BOOST_CONCEPT_ASSERT
         (
- (boost::geometry::concept::PointDistanceStrategy<haversine_type>)
+ (bg::concept::PointDistanceStrategy<haversine_type>)
         );
 
 
     static void test(double lon1, double lat1, double lon2, double lat2,
- double radius, double expected, double tolerance)
+ double radius, return_type expected, double tolerance)
     {
         haversine_type strategy(radius);
 
         Point p1, p2;
- boost::geometry::assign(p1, lon1, lat1);
- boost::geometry::assign(p2, lon2, lat2);
- typename haversine_type::return_type d1 = strategy.apply(p1, p2);
+ bg::assign(p1, lon1, lat1);
+ bg::assign(p2, lon2, lat2);
+ return_type d = strategy.apply(p1, p2);
 
- BOOST_CHECK_CLOSE((double) d1, expected, tolerance);
+ BOOST_CHECK_CLOSE(d, expected, tolerance);
     }
 };
 
 template <typename Point>
 void test_all()
 {
- double const average_earth_radius = 6372795.0;
 
     // earth to unit-sphere -> divide by earth circumference, then it is from 0-1,
     // then multiply with 2 PI, so effectively just divide by earth radius
     double e2u = 1.0 / average_earth_radius;
 
- // ~ Amsterdam/Paris
+ // ~ Amsterdam/Paris, 467 kilometers
     double const a_p = 467.2704 * 1000.0;
     test_distance<Point>::test(4, 52, 2, 48, average_earth_radius, a_p, 1.0);
     test_distance<Point>::test(2, 48, 4, 52, average_earth_radius, a_p, 1.0);
@@ -73,9 +85,177 @@
 }
 
 
+template <typename P1, typename P2, typename CalculationType>
+void test_services()
+{
+ P1 p1;
+ bg::assign(p1, 4, 52);
+
+ P2 p2;
+ bg::assign(p2, 2, 48);
+
+ // ~ Amsterdam/Paris, 467 kilometers
+ double const km = 1000.0;
+ double const a_p = 467.2704 * km;
+ double const expected = a_p;
+
+ double const expected_lower = 460.0 * km;
+ double const expected_higher = 470.0 * km;
+
+
+
+ namespace bgsd = bg::strategy::distance;
+ namespace services = bg::strategy::distance::services;
+ // 1: normal, calculate distance:
+
+ typedef bgsd::haversine<P1, P2, CalculationType> strategy_type;
+ typedef typename strategy_type::return_type return_type;
+
+ strategy_type strategy(average_earth_radius);
+ return_type result = strategy.apply(p1, p2);
+ BOOST_CHECK_CLOSE(result, return_type(expected), 0.001);
+
+ // 2: "similar" to construct a similar strategy (similar but with other template-parameters) for, e.g., the reverse P2/P1
+ // 2a: similar_type:
+ typedef typename services::similar_type<strategy_type, P2, P1>::type similar_type;
+ // 2b: get_similar
+ similar_type similar = services::get_similar<strategy_type, P2, P1>::apply(strategy);
+
+ //result = similar.apply(p1, p2); // should NOT compile because p1/p2 should also be reversed here
+ result = similar.apply(p2, p1);
+ BOOST_CHECK_CLOSE(result, return_type(expected), 0.001);
+
+
+ // 3: "comparable" to construct a "comparable strategy" for P1/P2
+ // a "comparable strategy" is a strategy which does not calculate the exact distance, but
+ // which returns results which can be mutually compared (e.g. avoid sqrt)
+
+ // 3a: "comparable_type"
+ typedef typename services::comparable_type<strategy_type>::type comparable_type;
+
+ // 3b: "get_comparable"
+ comparable_type comparable = bgsd::services::get_comparable<strategy_type>::apply(strategy);
+
+ // Check vice versa:
+ // First the result of the comparable strategy
+ return_type c_result = comparable.apply(p1, p2);
+ // Second the comparable result of the expected distance
+ return_type c_expected = services::result_from_distance<comparable_type>::apply(comparable, expected);
+ // And that one should be equa.
+ BOOST_CHECK_CLOSE(c_result, return_type(c_expected), 0.001);
+
+ // 4: the comparable_type should have a distance_strategy_constructor as well,
+ // knowing how to compare something with a fixed distance
+ return_type c_dist_lower = services::result_from_distance<comparable_type>::apply(comparable, expected_lower);
+ return_type c_dist_higher = services::result_from_distance<comparable_type>::apply(comparable, expected_higher);
+
+ // If this is the case:
+ BOOST_CHECK(c_dist_lower < c_result && c_result < c_dist_higher);
+
+ // Calculate the Haversine by hand here:
+ return_type c_check = return_type(2.0) * asin(sqrt(c_result)) * average_earth_radius;
+ BOOST_CHECK_CLOSE(c_check, expected, 0.001);
+
+ // This should also be the case
+ return_type dist_lower = services::result_from_distance<strategy_type>::apply(strategy, expected_lower);
+ return_type dist_higher = services::result_from_distance<strategy_type>::apply(strategy, expected_higher);
+ BOOST_CHECK(dist_lower < result && result < dist_higher);
+}
+
+template <typename P, typename Strategy>
+void time_compare_s(int const n)
+{
+ boost::timer t;
+ P p1, p2;
+ bg::assign(p1, 1, 1);
+ bg::assign(p2, 2, 2);
+ Strategy strategy;
+ typename Strategy::return_type s = 0;
+ for (int i = 0; i < n; i++)
+ {
+ for (int j = 0; j < n; j++)
+ {
+ s += strategy.apply(p1, p2);
+ }
+ }
+ std::cout << "s: " << s << " t: " << t.elapsed() << std::endl;
+}
+
+template <typename P>
+void time_compare(int const n)
+{
+ time_compare_s<P, bg::strategy::distance::haversine<P> >(n);
+ time_compare_s<P, bg::strategy::distance::comparable::haversine<P> >(n);
+}
+
+#include <time.h>
+double time_sqrt(int n)
+{
+ clock_t start = clock();
+
+ double v = 2.0;
+ double s = 0.0;
+ for (int i = 0; i < n; i++)
+ {
+ for (int j = 0; j < n; j++)
+ {
+ s += sqrt(v);
+ v += 1.0e-10;
+ }
+ }
+ clock_t end = clock();
+ double diff = double(end - start) / CLOCKS_PER_SEC;
+
+ std::cout << "Check: " << s << " Time: " << diff << std::endl;
+ return diff;
+}
+
+double time_normal(int n)
+{
+ clock_t start = clock();
+
+ double v = 2.0;
+ double s = 0.0;
+ for (int i = 0; i < n; i++)
+ {
+ for (int j = 0; j < n; j++)
+ {
+ s += v;
+ v += 1.0e-10;
+ }
+ }
+ clock_t end = clock();
+ double diff = double(end - start) / CLOCKS_PER_SEC;
+
+ std::cout << "Check: " << s << " Time: " << diff << std::endl;
+ return diff;
+}
+
+
 int test_main(int, char* [])
 {
- test_all<boost::geometry::point<double, 2, boost::geometry::cs::spherical<boost::geometry::degree> > >();
+ namespace bg = boost::geometry;
+ test_all<bg::point<int, 2, bg::cs::spherical<bg::degree> > >();
+ test_all<bg::point<float, 2, bg::cs::spherical<bg::degree> > >();
+ test_all<bg::point<double, 2, bg::cs::spherical<bg::degree> > >();
+
+ double t1 = time_sqrt(20000);
+ double t2 = time_normal(20000);
+ std::cout << "Factor: " << (t1 / t2) << std::endl;
+ time_compare<bg::point<double, 2, bg::cs::spherical<bg::radian> > >(10000);
+
+#if defined(HAVE_TTMATH)
+ typedef ttmath::Big<1,4> tt;
+ test_all<bg::point<tt, 2, bg::cs::spherical<bg::degree> > >();
+#endif
+
+
+ test_services
+ <
+ bg::point<float, 2, bg::cs::spherical<bg::degree> >,
+ bg::point<double, 2, bg::cs::spherical<bg::degree> >,
+ double
+ >();
 
     return 0;
 }

Modified: sandbox/geometry/libs/geometry/test/strategies/haversine.vcproj
==============================================================================
--- sandbox/geometry/libs/geometry/test/strategies/haversine.vcproj (original)
+++ sandbox/geometry/libs/geometry/test/strategies/haversine.vcproj 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -20,7 +20,7 @@
                         OutputDirectory="$(SolutionDir)$(ConfigurationName)"
                         IntermediateDirectory="$(ConfigurationName)\haversine"
                         ConfigurationType="1"
- InheritedPropertySheets="..\boost.vsprops"
+ InheritedPropertySheets="..\boost.vsprops;..\ttmath.vsprops"
                         CharacterSet="1"
>
                         <Tool
@@ -93,7 +93,7 @@
                         OutputDirectory="$(SolutionDir)$(ConfigurationName)"
                         IntermediateDirectory="$(ConfigurationName)\haversine"
                         ConfigurationType="1"
- InheritedPropertySheets="..\boost.vsprops"
+ InheritedPropertySheets="..\boost.vsprops;..\ttmath.vsprops"
                         CharacterSet="1"
                         WholeProgramOptimization="1"
>

Modified: sandbox/geometry/libs/geometry/test/strategies/projected_point.cpp
==============================================================================
--- sandbox/geometry/libs/geometry/test/strategies/projected_point.cpp (original)
+++ sandbox/geometry/libs/geometry/test/strategies/projected_point.cpp 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -20,17 +20,76 @@
 #include <boost/geometry/geometries/adapted/tuple_cartesian.hpp>
 #include <test_common/test_point.hpp>
 
+#ifdef HAVE_TTMATH
+# include <boost/geometry/extensions/contrib/ttmath_stub.hpp>
+#endif
+
+namespace bg = boost::geometry;
+
+
+template <typename P, typename PS, typename CalculationType>
+void test_services()
+{
+ PS p1, p2;
+ bg::assign(p1, 0, 0);
+ bg::assign(p2, 0, 4);
+
+ P p;
+ bg::assign(p, 2, 0);
+
+ double const sqr_expected = 4;
+ double const expected = 2;
+
+
+ namespace bgsd = bg::strategy::distance;
+ namespace services = bg::strategy::distance::services;
+ // 1: normal, calculate distance:
+
+ typedef bgsd::projected_point<P, PS, CalculationType> strategy_type;
+
+ BOOST_CONCEPT_ASSERT( (bg::concept::PointSegmentDistanceStrategy<strategy_type>) );
+
+ typedef typename strategy_type::return_type return_type;
+
+ strategy_type strategy;
+ return_type result = strategy.apply(p, p1, p2);
+ BOOST_CHECK_CLOSE(result, return_type(expected), 0.001);
+
+ // 2: "similar" to construct a similar strategy (similar but with other template-parameters) for, e.g., the reverse P2/P1
+ // 2a: similar_type:
+ typedef typename services::similar_type<strategy_type, P, PS>::type similar_type;
+ // 2b: get_similar
+ similar_type similar = services::get_similar<strategy_type, P, PS>::apply(strategy);
+
+ result = similar.apply(p, p1, p2);
+ BOOST_CHECK_CLOSE(result, return_type(expected), 0.001);
+
+
+ // 3: "comparable" to construct a "comparable strategy" for P1/P2
+ // a "comparable strategy" is a strategy which does not calculate the exact distance, but
+ // which returns results which can be mutually compared (e.g. avoid sqrt)
+
+ // 3a: "comparable_type"
+ typedef typename services::comparable_type<strategy_type>::type comparable_type;
+
+ // 3b: "get_comparable"
+ comparable_type comparable = bgsd::services::get_comparable<strategy_type>::apply(strategy);
+
+ return_type c_result = comparable.apply(p, p1, p2);
+ BOOST_CHECK_CLOSE(c_result, return_type(sqr_expected), 0.001);
+}
+
 
 template <typename P1, typename P2>
 void test_all_2d()
 {
     P1 p;
     P2 sp1, sp2;
- boost::geometry::read_wkt("POINT(1 1)", p);
- boost::geometry::read_wkt("POINT(0 0)", sp1);
- boost::geometry::read_wkt("POINT(2 3)", sp2);
+ bg::read_wkt("POINT(1 1)", p);
+ bg::read_wkt("POINT(0 0)", sp1);
+ bg::read_wkt("POINT(2 3)", sp2);
 
- typedef typename boost::geometry::strategy::distance::projected_point
+ typedef typename bg::strategy::distance::projected_point
         <
             P1,
             P2
@@ -38,61 +97,51 @@
 
     BOOST_CONCEPT_ASSERT
         (
- (boost::geometry::concept::PointSegmentDistanceStrategy<strategy_type>)
+ (bg::concept::PointSegmentDistanceStrategy<strategy_type>)
         );
 
 
     strategy_type strategy;
- std::cout << strategy.apply(p, sp1, sp2) << std::endl;
+ typename strategy_type::return_type d = strategy.apply(p, sp1, sp2);
+ BOOST_CHECK_CLOSE(d, 0.27735203958327, 0.001);
 }
 
 
 template <typename P>
 void test_all_2d()
 {
- using boost::geometry::point;
- using boost::geometry::cs::cartesian;
+ using bg::point;
+ using bg::cs::cartesian;
 
     //test_all_2d<P, int[2]>();
     //test_all_2d<P, float[2]>();
     //test_all_2d<P, double[2]>();
     //test_all_2d<P, test::test_point>();
- //test_all_2d<P, point<int, 2, cartesian> >();
- //test_all_2d<P, point<float, 2, cartesian> >();
+ test_all_2d<P, point<int, 2, cartesian> >();
+ test_all_2d<P, point<float, 2, cartesian> >();
     test_all_2d<P, point<double, 2, cartesian> >();
+ test_all_2d<P, point<long double, 2, cartesian> >();
 }
 
 int test_main(int, char* [])
 {
- using boost::geometry::point;
- using boost::geometry::cs::cartesian;
+ using bg::point;
+ using bg::cs::cartesian;
 
-#if ! defined(_MSC_VER)
     test_all_2d<int[2]>();
     test_all_2d<float[2]>();
     test_all_2d<double[2]>();
-#endif
     //test_all_2d<test::test_point>();
 
-#if ! defined(_MSC_VER)
     test_all_2d<point<int, 2, cartesian> >();
-#endif
     test_all_2d<point<float, 2, cartesian> >();
     test_all_2d<point<double, 2, cartesian> >();
 
+ test_services<point<double, 2, cartesian>, point<float, 2, cartesian>, long double>();
 
-#if defined(HAVE_CLN)
- // combination of CLN with normal types
- typedef boost::numeric_adaptor::cln_value_type cln_type;
- typedef point<cln_type, 2, cartesian> cln_point;
- test_all_2d<cln_point>();
-
-#endif
-#if defined(HAVE_GMP)
- typedef boost::numeric_adaptor::gmp_value_type gmp_type;
- typedef point<gmp_type, 2, cartesian> gmp_point;
- test_all_2d<gmp_point>();
 
+#if defined(HAVE_TTMATH)
+ test_all_2d<point<ttmath_big, 2, cartesian>, point<ttmath_big, 2, cartesian> >();
 #endif
 
     return 0;

Modified: sandbox/geometry/libs/geometry/test/strategies/projected_point.vcproj
==============================================================================
--- sandbox/geometry/libs/geometry/test/strategies/projected_point.vcproj (original)
+++ sandbox/geometry/libs/geometry/test/strategies/projected_point.vcproj 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -20,7 +20,7 @@
                         OutputDirectory="$(SolutionDir)$(ConfigurationName)"
                         IntermediateDirectory="$(ConfigurationName)\projected_point"
                         ConfigurationType="1"
- InheritedPropertySheets="..\boost.vsprops"
+ InheritedPropertySheets="..\boost.vsprops;..\ttmath.vsprops"
                         CharacterSet="1"
>
                         <Tool
@@ -93,7 +93,7 @@
                         OutputDirectory="$(SolutionDir)$(ConfigurationName)"
                         IntermediateDirectory="$(ConfigurationName)\projected_point"
                         ConfigurationType="1"
- InheritedPropertySheets="..\boost.vsprops"
+ InheritedPropertySheets="..\boost.vsprops;..\ttmath.vsprops"
                         CharacterSet="1"
                         WholeProgramOptimization="1"
>

Modified: sandbox/geometry/libs/geometry/test/strategies/pythagoras.cpp
==============================================================================
--- sandbox/geometry/libs/geometry/test/strategies/pythagoras.cpp (original)
+++ sandbox/geometry/libs/geometry/test/strategies/pythagoras.cpp 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -9,68 +9,176 @@
 
 #include <geometry_test_common.hpp>
 
+#if defined(_MSC_VER)
+# pragma warning( disable : 4101 )
+#endif
+
+#include <boost/timer.hpp>
+
+#include <boost/concept/requires.hpp>
+#include <boost/concept_check.hpp>
+
 #include <boost/geometry/algorithms/assign.hpp>
 #include <boost/geometry/strategies/cartesian/distance_pythagoras.hpp>
+#include <boost/geometry/strategies/concepts/distance_concept.hpp>
 
 
 #include <boost/geometry/geometries/point.hpp>
 #include <boost/geometry/geometries/adapted/c_array_cartesian.hpp>
 #include <boost/geometry/geometries/adapted/tuple_cartesian.hpp>
+
 #include <test_common/test_point.hpp>
 
+#ifdef HAVE_TTMATH
+# include <boost/geometry/extensions/contrib/ttmath_stub.hpp>
+#endif
+
+
+namespace bg = boost::geometry;
+
 template <typename P1, typename P2>
 void test_null_distance_3d()
 {
- typename boost::geometry::strategy::distance::pythagoras<P1, P2> pythagoras;
-
     P1 p1;
- boost::geometry::assign(p1, 1, 2, 3);
+ bg::assign(p1, 1, 2, 3);
     P2 p2;
- boost::geometry::assign(p2, 1, 2, 3);
- BOOST_CHECK_EQUAL(double(
- typename boost::geometry::coordinate_type<P1>::type(pythagoras.apply(p1, p2))), 0);
+ bg::assign(p2, 1, 2, 3);
+
+ typedef bg::strategy::distance::pythagoras<P1, P2> pythagoras_type;
+ typedef typename pythagoras_type::return_type return_type;
+
+ pythagoras_type pythagoras;
+ return_type result = pythagoras.apply(p1, p2);
+
+ BOOST_CHECK_EQUAL(result, return_type(0));
 }
 
 template <typename P1, typename P2>
 void test_axis_3d()
 {
- boost::geometry::strategy::distance::pythagoras<P1, P2> pythagoras;
-
     P1 p1;
- boost::geometry::assign(p1, 0, 0, 0);
-
+ bg::assign(p1, 0, 0, 0);
     P2 p2;
- boost::geometry::assign(p2, 1, 0, 0);
- BOOST_CHECK_EQUAL(double(
- typename boost::geometry::coordinate_type<P1>::type(pythagoras.apply(p1, p2))), 1);
- boost::geometry::assign(p2, 0, 1, 0);
- BOOST_CHECK_EQUAL(double(
- typename boost::geometry::coordinate_type<P1>::type(pythagoras.apply(p1, p2))), 1);
- boost::geometry::assign(p2, 0, 0, 1);
- BOOST_CHECK_EQUAL(double(
- typename boost::geometry::coordinate_type<P1>::type(pythagoras.apply(p1, p2))), 1);
+ bg::assign(p2, 1, 0, 0);
+
+ typedef bg::strategy::distance::pythagoras<P1, P2> pythagoras_type;
+ typedef typename pythagoras_type::return_type return_type;
+
+ pythagoras_type pythagoras;
+
+ return_type result = pythagoras.apply(p1, p2);
+ BOOST_CHECK_EQUAL(result, return_type(1));
+
+ bg::assign(p2, 0, 1, 0);
+ result = pythagoras.apply(p1, p2);
+ BOOST_CHECK_EQUAL(result, return_type(1));
+
+ bg::assign(p2, 0, 0, 1);
+ result = pythagoras.apply(p1, p2);
+ BOOST_CHECK_CLOSE(result, return_type(1), 0.001);
 }
 
 template <typename P1, typename P2>
 void test_arbitrary_3d()
 {
- boost::geometry::strategy::distance::pythagoras<P1, P2> pythagoras;
+ P1 p1;
+ bg::assign(p1, 1, 2, 3);
+ P2 p2;
+ bg::assign(p2, 9, 8, 7);
+
+ {
+ typedef bg::strategy::distance::pythagoras<P1, P2> strategy_type;
+ typedef typename strategy_type::return_type return_type;
+
+ strategy_type strategy;
+ return_type result = strategy.apply(p1, p2);
+ BOOST_CHECK_CLOSE(result, return_type(10.77032961427), 0.001);
+ }
+
+ {
+ // Check comparable distance
+ typedef bg::strategy::distance::comparable::pythagoras<P1, P2> strategy_type;
+ typedef typename strategy_type::return_type return_type;
+
+ strategy_type strategy;
+ return_type result = strategy.apply(p1, p2);
+ BOOST_CHECK_EQUAL(result, return_type(116));
+ }
+}
+
+template <typename P1, typename P2, typename CalculationType>
+void test_services()
+{
 
     P1 p1;
- boost::geometry::assign(p1, 1, 2, 3);
+ bg::assign(p1, 1, 2, 3);
+
     P2 p2;
- boost::geometry::assign(p2, 9, 8, 7);
- BOOST_CHECK_CLOSE(double(
- typename boost::geometry::coordinate_type<P1>::type(pythagoras.apply(p1, p2))),
- sqrt((double)116), 0.001);
+ bg::assign(p2, 4, 5, 6);
+
+ double const sqr_expected = 3*3 + 3*3 + 3*3; // 27
+ double const expected = sqrt(sqr_expected); // sqrt(27)=5.1961524227
+
+
+ namespace bgsd = boost::geometry::strategy::distance;
+ namespace services = boost::geometry::strategy::distance::services;
+ // 1: normal, calculate distance:
+
+ typedef bgsd::pythagoras<P1, P2, CalculationType> strategy_type;
+
+ BOOST_CONCEPT_ASSERT( (boost::geometry::concept::PointDistanceStrategy<strategy_type>) );
+
+ typedef typename strategy_type::return_type return_type;
+
+ strategy_type strategy;
+ return_type result = strategy.apply(p1, p2);
+ BOOST_CHECK_CLOSE(result, return_type(expected), 0.001);
+
+ // 2: "similar" to construct a similar strategy (similar but with other template-parameters) for, e.g., the reverse P2/P1
+ // 2a: similar_type:
+ typedef typename services::similar_type<strategy_type, P2, P1>::type similar_type;
+ // 2b: get_similar
+ similar_type similar = services::get_similar<strategy_type, P2, P1>::apply(strategy);
+
+ //result = similar.apply(p1, p2); // should NOT compile because p1/p2 should also be reversed here
+ result = similar.apply(p2, p1);
+ BOOST_CHECK_CLOSE(result, return_type(expected), 0.001);
+
+
+ // 3: "comparable" to construct a "comparable strategy" for P1/P2
+ // a "comparable strategy" is a strategy which does not calculate the exact distance, but
+ // which returns results which can be mutually compared (e.g. avoid sqrt)
+
+ // 3a: "comparable_type"
+ typedef typename services::comparable_type<strategy_type>::type comparable_type;
+
+ // 3b: "get_comparable"
+ comparable_type comparable = bgsd::services::get_comparable<strategy_type>::apply(strategy);
+
+ return_type c_result = comparable.apply(p1, p2);
+ BOOST_CHECK_CLOSE(c_result, return_type(sqr_expected), 0.001);
+
+ // 4: the comparable_type should have a distance_strategy_constructor as well,
+ // knowing how to compare something with a fixed distance
+ return_type c_dist5 = services::result_from_distance<comparable_type>::apply(comparable, 5.0);
+ return_type c_dist6 = services::result_from_distance<comparable_type>::apply(comparable, 6.0);
+
+ // If this is the case:
+ BOOST_CHECK(c_dist5 < c_result && c_result < c_dist6);
+
+ // This should also be the case
+ return_type dist5 = services::result_from_distance<strategy_type>::apply(strategy, 5.0);
+ return_type dist6 = services::result_from_distance<strategy_type>::apply(strategy, 6.0);
+ BOOST_CHECK(dist5 < result && result < dist6);
 }
 
+
 template <typename CoordinateType, typename CalculationType, typename AssignType>
 void test_big_2d_with(AssignType const& x1, AssignType const& y1,
                  AssignType const& x2, AssignType const& y2)
 {
- typedef boost::geometry::point<CoordinateType, 2, boost::geometry::cs::cartesian> point_type;
- typedef boost::geometry::strategy::distance::pythagoras
+ typedef bg::point<CoordinateType, 2, bg::cs::cartesian> point_type;
+ typedef bg::strategy::distance::pythagoras
         <
             point_type,
             point_type,
@@ -78,23 +186,22 @@
> pythagoras_type;
 
     pythagoras_type pythagoras;
+ typedef typename pythagoras_type::return_type return_type;
 
 
     point_type p1, p2;
- boost::geometry::assign(p1, x1, y1);
- boost::geometry::assign(p2, x2, y2);
- typename pythagoras_type::return_type d1 = pythagoras.apply(p1, p2);
+ bg::assign(p1, x1, y1);
+ bg::assign(p2, x2, y2);
+ return_type d = pythagoras.apply(p1, p2);
 
- /*
+ /***
     std::cout << typeid(CalculationType).name()
- << " " << std::fixed << std::setprecision(20) << d1.squared_value()
+ << " " << std::fixed << std::setprecision(20) << d
         << std::endl << std::endl;
- */
+ ***/
 
- CalculationType d2 = d1;
 
- BOOST_CHECK_CLOSE((double) d2,
- 1076554.5485833955678294387789057, 0.001);
+ BOOST_CHECK_CLOSE(d, return_type(1076554.5485833955678294387789057), 0.001);
 }
 
 template <typename CoordinateType, typename CalculationType>
@@ -118,7 +225,6 @@
 template <typename P1, typename P2>
 void test_all_3d()
 {
-return;
     test_null_distance_3d<P1, P2>();
     test_axis_3d<P1, P2>();
     test_arbitrary_3d<P1, P2>();
@@ -127,8 +233,8 @@
 template <typename P>
 void test_all_3d()
 {
- using boost::geometry::point;
- using boost::geometry::cs::cartesian;
+ using bg::point;
+ using bg::cs::cartesian;
 
     test_all_3d<P, int[3]>();
     test_all_3d<P, float[3]>();
@@ -139,20 +245,45 @@
     test_all_3d<P, point<double, 3, cartesian> >();
 }
 
+template <typename P, typename Strategy>
+void time_compare_s(int const n)
+{
+ boost::timer t;
+ P p1, p2;
+ bg::assign(p1, 1, 1);
+ bg::assign(p2, 2, 2);
+ Strategy strategy;
+ typename Strategy::return_type s = 0;
+ for (int i = 0; i < n; i++)
+ {
+ for (int j = 0; j < n; j++)
+ {
+ bg::set<0>(p2, bg::get<0>(p2) + 0.001);
+ s += strategy.apply(p1, p2);
+ }
+ }
+ std::cout << "s: " << s << " t: " << t.elapsed() << std::endl;
+}
+
+template <typename P>
+void time_compare(int const n)
+{
+ time_compare_s<P, bg::strategy::distance::pythagoras<P> >(n);
+ time_compare_s<P, bg::strategy::distance::comparable::pythagoras<P> >(n);
+}
+
 int test_main(int, char* [])
 {
- using boost::geometry::point;
- using boost::geometry::cs::cartesian;
+ using bg::point;
+ using bg::cs::cartesian;
 
-#if ! defined(_MSC_VER)
     test_all_3d<int[3]>();
-#endif
     test_all_3d<float[3]>();
     test_all_3d<double[3]>();
+
     test_all_3d<test::test_point>();
-#if ! defined(_MSC_VER)
+
     test_all_3d<point<int, 3, cartesian> >();
-#endif
     test_all_3d<point<float, 3, cartesian> >();
     test_all_3d<point<double, 3, cartesian> >();
 
@@ -161,29 +292,22 @@
     test_big_2d<long double, long double>();
     test_big_2d<float, long double>();
 
-/*
-TODO: fix this, assign type should use boost::to etc
+ test_services<point<float, 3, cartesian>, double[3], long double>();
+ test_services<double[3], test::test_point, float>();
 
-#if defined(HAVE_CLN)
- // combination of CLN with normal types
- typedef boost::numeric_adaptor::cln_value_type cln_type;
- typedef point<cln_type, 3, cartesian> cln_point;
- test_all_3d<cln_point>();
- test_all_3d<cln_point, cln_point>();
 
- test_big_2d<cln_type, cln_type>();
- test_big_2d_string<cln_type, cln_type>();
+ time_compare<point<double, 2, cartesian> >(10000);
 
-#endif
-#if defined(HAVE_GMP)
- typedef boost::numeric_adaptor::gmp_value_type gmp_type;
- typedef point<gmp_type, 3, cartesian> gmp_point;
- test_all_3d<gmp_point>();
- test_all_3d<gmp_point, gmp_point>();
+#if defined(HAVE_TTMATH)
+
+ typedef ttmath::Big<1,4> tt;
+ typedef point<tt, 3, cartesian> tt_point;
 
- test_big_2d<gmp_type, gmp_type>();
- test_big_2d_string<gmp_type, gmp_type>();
+ //test_all_3d<tt[3]>();
+ test_all_3d<tt_point>();
+ test_all_3d<tt_point, tt_point>();
+ test_big_2d<tt, tt>();
+ test_big_2d_string<tt, tt>();
 #endif
-*/
     return 0;
 }

Modified: sandbox/geometry/libs/geometry/test/strategies/pythagoras.vcproj
==============================================================================
--- sandbox/geometry/libs/geometry/test/strategies/pythagoras.vcproj (original)
+++ sandbox/geometry/libs/geometry/test/strategies/pythagoras.vcproj 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -20,7 +20,7 @@
                         OutputDirectory="$(SolutionDir)$(ConfigurationName)"
                         IntermediateDirectory="$(ConfigurationName)\pythagoras"
                         ConfigurationType="1"
- InheritedPropertySheets="..\boost.vsprops"
+ InheritedPropertySheets="..\boost.vsprops;..\ttmath.vsprops"
                         CharacterSet="1"
>
                         <Tool
@@ -93,7 +93,7 @@
                         OutputDirectory="$(SolutionDir)$(ConfigurationName)"
                         IntermediateDirectory="$(ConfigurationName)\pythagoras"
                         ConfigurationType="1"
- InheritedPropertySheets="..\boost.vsprops"
+ InheritedPropertySheets="..\boost.vsprops;..\ttmath.vsprops"
                         CharacterSet="1"
                         WholeProgramOptimization="1"
>

Added: sandbox/geometry/libs/geometry/test/ttmath.vsprops
==============================================================================
--- (empty file)
+++ sandbox/geometry/libs/geometry/test/ttmath.vsprops 2010-07-04 06:01:10 EDT (Sun, 04 Jul 2010)
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioPropertySheet
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="ttmath"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="$(TTMATH_ROOT)"
+ PreprocessorDefinitions="HAVE_TTMATH"
+ />
+ <UserMacro
+ Name="TTMATH_ROOT"
+ Value="../../../../boost/geometry/extensions/contrib"
+ />
+</VisualStudioPropertySheet>


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