From 46763d34ca51d284421a11f1882a070c1f901ea7 Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Thu, 15 May 2014 02:24:42 +0300 Subject: [PATCH 1/4] [strategies] fix conversion issue in projected_point strategy: Problem: when p1 (2nd argument of apply) has float as coordinate type, then the result of the differences u-p1 and w-p1 is a double (because the calculation type is double), which then is implicitly converted to float (because the result of the difference is implicitly converted to the type of the second operand), which means that we may loose precision. Solution: convert p1 to the correct point type (fp_point_type), and then perform the subtractions (p1 is anyways converted later on, so just do then conversion a bit earlier). Note: This problem was generated as a warning on VS2010, and also appears as a warning in clang++ and g++ if the -Wconversion option is used. --- .../cartesian/distance_projected_point.hpp | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/include/boost/geometry/strategies/cartesian/distance_projected_point.hpp b/include/boost/geometry/strategies/cartesian/distance_projected_point.hpp index cd86b523f..329b7d4e4 100644 --- a/include/boost/geometry/strategies/cartesian/distance_projected_point.hpp +++ b/include/boost/geometry/strategies/cartesian/distance_projected_point.hpp @@ -1,8 +1,13 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2008-2012 Bruno Lalande, Paris, France. -// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands. -// Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +// Copyright (c) 2008-2014 Bruno Lalande, Paris, France. +// Copyright (c) 2008-2014 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2009-2014 Mateusz Loskot, London, UK. + +// This file was modified by Oracle on 2014. +// Modifications copyright (c) 2014, Oracle and/or its affiliates. + +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -124,12 +129,13 @@ public : // 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; + fp_vector_type v, w, projected; geometry::convert(p2, v); geometry::convert(p, w); - subtract_point(v, p1); - subtract_point(w, p1); + geometry::convert(p1, projected); + subtract_point(v, projected); + subtract_point(w, projected); Strategy strategy; boost::ignore_unused_variable_warning(strategy); @@ -149,8 +155,6 @@ public : // See above, c1 > 0 AND c2 > c1 so: c2 != 0 calculation_type const b = c1 / c2; - fp_point_type projected; - geometry::convert(p1, projected); multiply_value(v, b); add_point(projected, v); From fe8027d303c66363b2c5eda7956ed4223cdc164e Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Thu, 15 May 2014 18:38:45 +0300 Subject: [PATCH 2/4] [test] add missing include (#include ) --- test/string_from_type.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/test/string_from_type.hpp b/test/string_from_type.hpp index b564c2359..178ff2ea0 100644 --- a/test/string_from_type.hpp +++ b/test/string_from_type.hpp @@ -14,6 +14,7 @@ #ifndef GEOMETRY_TEST_STRING_FROM_TYPE_HPP #define GEOMETRY_TEST_STRING_FROM_TYPE_HPP +#include #if defined(HAVE_TTMATH) # include From 96a2f382a2549a3ff52d5f9918c8ee2b6bd36400 Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Fri, 16 May 2014 13:58:43 +0300 Subject: [PATCH 3/4] [distance] implement the new file/directory structure fully: move the free function and reverse dispatch in algorithms/distance/interface.hpp move the details of the implementation in algorithms/distance/implementation.hpp keep only these two headers in algorithms/distance.hpp --- .../detail/distance/implementation.hpp | 38 ++++ .../algorithms/detail/distance/interface.hpp | 183 ++++++++++++++++++ 2 files changed, 221 insertions(+) create mode 100644 include/boost/geometry/algorithms/detail/distance/implementation.hpp create mode 100644 include/boost/geometry/algorithms/detail/distance/interface.hpp diff --git a/include/boost/geometry/algorithms/detail/distance/implementation.hpp b/include/boost/geometry/algorithms/detail/distance/implementation.hpp new file mode 100644 index 000000000..45f40bbb3 --- /dev/null +++ b/include/boost/geometry/algorithms/detail/distance/implementation.hpp @@ -0,0 +1,38 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2008-2014 Bruno Lalande, Paris, France. +// Copyright (c) 2009-2014 Mateusz Loskot, London, UK. +// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland. + +// This file was modified by Oracle on 2014. +// Modifications copyright (c) 2014, Oracle and/or its affiliates. + +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle + +// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library +// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_IMPLEMENTATION_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_IMPLEMENTATION_HPP + +// the implementation details +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_IMPLEMENTATION_HPP diff --git a/include/boost/geometry/algorithms/detail/distance/interface.hpp b/include/boost/geometry/algorithms/detail/distance/interface.hpp new file mode 100644 index 000000000..6b7b68fcb --- /dev/null +++ b/include/boost/geometry/algorithms/detail/distance/interface.hpp @@ -0,0 +1,183 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2008-2014 Bruno Lalande, Paris, France. +// Copyright (c) 2009-2014 Mateusz Loskot, London, UK. +// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland. + +// This file was modified by Oracle on 2014. +// Modifications copyright (c) 2014, Oracle and/or its affiliates. + +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle + +// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library +// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. + +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_INTERFACE_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_INTERFACE_HPP + +#include + +#include +#include + +#include +#include + +#include + +#include +#include + +#include +#include + +#include + +#include + + +namespace boost { namespace geometry +{ + + +#ifndef DOXYGEN_NO_DISPATCH +namespace dispatch +{ + + +// If reversal is needed, perform it +template +< + typename Geometry1, typename Geometry2, typename Strategy, + typename Tag1, typename Tag2, typename StrategyTag +> +struct distance +< + Geometry1, Geometry2, Strategy, + Tag1, Tag2, StrategyTag, + true +> + : distance +{ + typedef typename strategy::distance::services::return_type + < + Strategy, + typename point_type::type, + typename point_type::type + >::type return_type; + + static inline return_type apply( + Geometry1 const& g1, + Geometry2 const& g2, + Strategy const& strategy) + { + return distance + < + Geometry2, Geometry1, Strategy, + Tag2, Tag1, StrategyTag, + false + >::apply(g2, g1, strategy); + } +}; + + +} // namespace dispatch +#endif // DOXYGEN_NO_DISPATCH + +/*! +\brief \brief_calc2{distance} \brief_strategy +\ingroup distance +\details +\details \details_calc{area}. \brief_strategy. \details_strategy_reasons + +\tparam Geometry1 \tparam_geometry +\tparam Geometry2 \tparam_geometry +\tparam Strategy \tparam_strategy{Distance} +\param geometry1 \param_geometry +\param geometry2 \param_geometry +\param strategy \param_strategy{distance} +\return \return_calc{distance} +\note The strategy can be a point-point strategy. In case of distance point-line/point-polygon + it may also be a point-segment strategy. + +\qbk{distinguish,with strategy} + +\qbk{ +[heading Available Strategies] +\* [link geometry.reference.strategies.strategy_distance_pythagoras Pythagoras (cartesian)] +\* [link geometry.reference.strategies.strategy_distance_haversine Haversine (spherical)] +\* [link geometry.reference.strategies.strategy_distance_cross_track Cross track (spherical\, point-to-segment)] +\* [link geometry.reference.strategies.strategy_distance_projected_point Projected point (cartesian\, point-to-segment)] +\* more (currently extensions): Vincenty\, Andoyer (geographic) +} + */ + +/* +Note, in case of a Compilation Error: +if you get: + - "Failed to specialize function template ..." + - "error: no matching function for call to ..." +for distance, it is probably so that there is no specialization +for return_type<...> for your strategy. +*/ +template +inline typename strategy::distance::services::return_type + < + Strategy, + typename point_type::type, + typename point_type::type + >::type +distance(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) +{ + concept::check(); + concept::check(); + + detail::throw_on_empty_input(geometry1); + detail::throw_on_empty_input(geometry2); + + return dispatch::distance + < + Geometry1, + Geometry2, + Strategy + >::apply(geometry1, geometry2, strategy); +} + + +/*! +\brief \brief_calc2{distance} +\ingroup distance +\details The default strategy is used, corresponding to the coordinate system of the geometries +\tparam Geometry1 \tparam_geometry +\tparam Geometry2 \tparam_geometry +\param geometry1 \param_geometry +\param geometry2 \param_geometry +\return \return_calc{distance} + +\qbk{[include reference/algorithms/distance.qbk]} + */ +template +inline typename default_distance_result::type distance( + Geometry1 const& geometry1, Geometry2 const& geometry2) +{ + concept::check(); + concept::check(); + + typedef typename detail::distance::default_strategy + < + Geometry1, Geometry2 + >::type default_strategy_type; + + return distance(geometry1, geometry2, default_strategy_type()); +} + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_INTERFACE_HPP From 3fbfd2474d9cabcd0ee5568b1ae07199124a5a82 Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Fri, 16 May 2014 14:14:26 +0300 Subject: [PATCH 4/4] [distance] implement the new file/directory structure fully: move the free function and reverse dispatch in algorithms/distance/interface.hpp move the details of the implementation in algorithms/distance/implementation.hpp keep only these two headers in algorithms/distance.hpp --- .../boost/geometry/algorithms/distance.hpp | 186 +----------------- 1 file changed, 2 insertions(+), 184 deletions(-) diff --git a/include/boost/geometry/algorithms/distance.hpp b/include/boost/geometry/algorithms/distance.hpp index 36ff3a695..dcfe597cd 100644 --- a/include/boost/geometry/algorithms/distance.hpp +++ b/include/boost/geometry/algorithms/distance.hpp @@ -20,189 +20,7 @@ #ifndef BOOST_GEOMETRY_ALGORITHMS_DISTANCE_HPP #define BOOST_GEOMETRY_ALGORITHMS_DISTANCE_HPP -#include -#include - -#include - -#include -#include -#include -#include - -#include -#include - -#include - -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include - -#include - - -namespace boost { namespace geometry -{ - - -#ifndef DOXYGEN_NO_DISPATCH -namespace dispatch -{ - - -// If reversal is needed, perform it -template -< - typename Geometry1, typename Geometry2, typename Strategy, - typename Tag1, typename Tag2, typename StrategyTag -> -struct distance -< - Geometry1, Geometry2, Strategy, - Tag1, Tag2, StrategyTag, - true -> - : distance -{ - typedef typename strategy::distance::services::return_type - < - Strategy, - typename point_type::type, - typename point_type::type - >::type return_type; - - static inline return_type apply( - Geometry1 const& g1, - Geometry2 const& g2, - Strategy const& strategy) - { - return distance - < - Geometry2, Geometry1, Strategy, - Tag2, Tag1, StrategyTag, - false - >::apply(g2, g1, strategy); - } -}; - - -} // namespace dispatch -#endif // DOXYGEN_NO_DISPATCH - -/*! -\brief \brief_calc2{distance} \brief_strategy -\ingroup distance -\details -\details \details_calc{area}. \brief_strategy. \details_strategy_reasons - -\tparam Geometry1 \tparam_geometry -\tparam Geometry2 \tparam_geometry -\tparam Strategy \tparam_strategy{Distance} -\param geometry1 \param_geometry -\param geometry2 \param_geometry -\param strategy \param_strategy{distance} -\return \return_calc{distance} -\note The strategy can be a point-point strategy. In case of distance point-line/point-polygon - it may also be a point-segment strategy. - -\qbk{distinguish,with strategy} - -\qbk{ -[heading Available Strategies] -\* [link geometry.reference.strategies.strategy_distance_pythagoras Pythagoras (cartesian)] -\* [link geometry.reference.strategies.strategy_distance_haversine Haversine (spherical)] -\* [link geometry.reference.strategies.strategy_distance_cross_track Cross track (spherical\, point-to-segment)] -\* [link geometry.reference.strategies.strategy_distance_projected_point Projected point (cartesian\, point-to-segment)] -\* more (currently extensions): Vincenty\, Andoyer (geographic) -} - */ - -/* -Note, in case of a Compilation Error: -if you get: - - "Failed to specialize function template ..." - - "error: no matching function for call to ..." -for distance, it is probably so that there is no specialization -for return_type<...> for your strategy. -*/ -template -inline typename strategy::distance::services::return_type - < - Strategy, - typename point_type::type, - typename point_type::type - >::type -distance(Geometry1 const& geometry1, - Geometry2 const& geometry2, - Strategy const& strategy) -{ - concept::check(); - concept::check(); - - detail::throw_on_empty_input(geometry1); - detail::throw_on_empty_input(geometry2); - - return dispatch::distance - < - Geometry1, - Geometry2, - Strategy - >::apply(geometry1, geometry2, strategy); -} - - -/*! -\brief \brief_calc2{distance} -\ingroup distance -\details The default strategy is used, corresponding to the coordinate system of the geometries -\tparam Geometry1 \tparam_geometry -\tparam Geometry2 \tparam_geometry -\param geometry1 \param_geometry -\param geometry2 \param_geometry -\return \return_calc{distance} - -\qbk{[include reference/algorithms/distance.qbk]} - */ -template -inline typename default_distance_result::type distance( - Geometry1 const& geometry1, Geometry2 const& geometry2) -{ - concept::check(); - concept::check(); - - typedef typename detail::distance::default_strategy - < - Geometry1, Geometry2 - >::type default_strategy_type; - - return distance(geometry1, geometry2, default_strategy_type()); -} - -}} // namespace boost::geometry - - -// the implementation details -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include +#include +#include #endif // BOOST_GEOMETRY_ALGORITHMS_DISTANCE_HPP