diff --git a/extensions/test/gis/latlong/andoyer.cpp b/extensions/test/gis/latlong/andoyer.cpp index 80e971bc2..edce7b9de 100644 --- a/extensions/test/gis/latlong/andoyer.cpp +++ b/extensions/test/gis/latlong/andoyer.cpp @@ -5,6 +5,11 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 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 Adam Wulkiewicz, 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. @@ -19,6 +24,7 @@ #include +#include #include #include #include @@ -39,7 +45,9 @@ void test_andoyer(double lon1, double lat1, double lon2, double lat2, double exp typename bg::coordinate_type::type >::type rtype; - typedef bg::strategy::distance::andoyer andoyer_type; + typedef bg::srs::spheroid stype; + + typedef bg::strategy::distance::andoyer andoyer_type; BOOST_CONCEPT_ASSERT ( diff --git a/extensions/test/gis/latlong/vincenty.cpp b/extensions/test/gis/latlong/vincenty.cpp index a11dfd640..70348dc4d 100644 --- a/extensions/test/gis/latlong/vincenty.cpp +++ b/extensions/test/gis/latlong/vincenty.cpp @@ -5,6 +5,11 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 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 Adam Wulkiewicz, 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. @@ -19,6 +24,7 @@ #include +#include #include #include #include @@ -39,7 +45,9 @@ void test_vincenty(double lon1, double lat1, double lon2, double lat2, double ex typename bg::coordinate_type::type >::type rtype; - typedef bg::strategy::distance::vincenty vincenty_type; + typedef bg::srs::spheroid stype; + + typedef bg::strategy::distance::vincenty vincenty_type; BOOST_CONCEPT_ASSERT( ( diff --git a/extensions/test/nsphere/nsphere-circle.cpp b/extensions/test/nsphere/nsphere-circle.cpp index a88bc9b28..f4ae392e2 100644 --- a/extensions/test/nsphere/nsphere-circle.cpp +++ b/extensions/test/nsphere/nsphere-circle.cpp @@ -81,7 +81,7 @@ struct access }; template<> -struct radius_access +struct radius_access { static inline int get(custom_circle const& c) { diff --git a/include/boost/geometry/algorithms/detail/flattening.hpp b/include/boost/geometry/algorithms/detail/flattening.hpp new file mode 100644 index 000000000..a679246d9 --- /dev/null +++ b/include/boost/geometry/algorithms/detail/flattening.hpp @@ -0,0 +1,69 @@ +// Boost.Geometry + +// Copyright (c) 2014 Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// 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_FLATTENING_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_FLATTENING_HPP + +#include +#include +#include + +#include + +namespace boost { namespace geometry +{ + +#ifndef DOXYGEN_NO_DISPATCH +namespace detail_dispatch +{ + +template ::type> +struct flattening + : not_implemented +{}; + +template +struct flattening +{ + static inline ResultType apply(Geometry const& geometry) + { + return ResultType(0); + } +}; + +template +struct flattening +{ + static inline ResultType apply(Geometry const& geometry) + { + return ResultType(get_radius<0>(geometry) - get_radius<2>(geometry)) + / ResultType(get_radius<0>(geometry)); + } +}; + +} // namespace detail_dispatch +#endif // DOXYGEN_NO_DISPATCH + +#ifndef DOXYGEN_NO_DETAIL +namespace detail +{ + +template +ResultType flattening(Geometry const& geometry) +{ + return detail_dispatch::flattening::apply(geometry); +} + +} // namespace detail +#endif // DOXYGEN_NO_DETAIL + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_FLATTENING_HPP diff --git a/include/boost/geometry/core/radius.hpp b/include/boost/geometry/core/radius.hpp new file mode 100644 index 000000000..ee6d5d246 --- /dev/null +++ b/include/boost/geometry/core/radius.hpp @@ -0,0 +1,250 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2008-2012 Bruno Lalande, Paris, France. +// Copyright (c) 2009-2012 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 Adam Wulkiewicz, 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_CORE_RADIUS_HPP +#define BOOST_GEOMETRY_CORE_RADIUS_HPP + + +#include + +#include + +#include +#include +#include + + +namespace boost { namespace geometry +{ + +namespace traits +{ + +/*! + \brief Traits class to get/set radius of a circle/sphere/(ellipse) + \details the radius access meta-functions give read/write access to the radius of a circle or a sphere, + or to the major/minor axis or an ellipse, or to one of the 3 equatorial radii of an ellipsoid. + + It should be specialized per geometry, in namespace core_dispatch. Those specializations should + forward the call via traits to the geometry class, which could be specified by the user. + + There is a corresponding generic radius_get and radius_set function + \par Geometries: + - n-sphere (circle,sphere) + - upcoming ellipse + \par Specializations should provide: + - inline static T get(Geometry const& geometry) + - inline static void set(Geometry& geometry, T const& radius) + \ingroup traits +*/ +template +struct radius_access {}; + + +/*! + \brief Traits class indicating the type (double,float,...) of the radius of a circle or a sphere + \par Geometries: + - n-sphere (circle,sphere) + - upcoming ellipse + \par Specializations should provide: + - typedef T type (double,float,int,etc) + \ingroup traits +*/ +template +struct radius_type {}; + +} // namespace traits + + +#ifndef DOXYGEN_NO_DISPATCH +namespace core_dispatch +{ + +template +struct radius_type +{ + //typedef core_dispatch_specialization_required type; +}; + +/*! + \brief radius access meta-functions, used by concept n-sphere and upcoming ellipse. +*/ +template +struct radius_access +{ + //static inline CoordinateType get(Geometry const& ) {} + //static inline void set(Geometry& g, CoordinateType const& value) {} +}; + +} // namespace core_dispatch +#endif // DOXYGEN_NO_DISPATCH + + +/*! + \brief Metafunction to get the type of radius of a circle / sphere / ellipse / etc. + \ingroup access + \tparam Geometry the type of geometry +*/ +template +struct radius_type +{ + typedef typename core_dispatch::radius_type + < + typename tag::type, + typename util::bare_type::type + >::type type; +}; + +/*! + \brief Function to get radius of a circle / sphere / ellipse / etc. + \return radius The radius for a given axis + \ingroup access + \param geometry the geometry to get the radius from + \tparam I index of the axis +*/ +template +inline typename radius_type::type get_radius(Geometry const& geometry) +{ + return core_dispatch::radius_access + < + typename tag::type, + typename util::bare_type::type, + I, + typename boost::is_pointer::type + >::get(geometry); +} + +/*! + \brief Function to set the radius of a circle / sphere / ellipse / etc. + \ingroup access + \tparam I index of the axis + \param geometry the geometry to change + \param radius the radius to set +*/ +template +inline void set_radius(Geometry& geometry, + typename radius_type::type const& radius) +{ + core_dispatch::radius_access + < + typename tag::type, + typename util::bare_type::type, + I, + typename boost::is_pointer::type + >::set(geometry, radius); +} + + + +#ifndef DOXYGEN_NO_DETAIL +namespace detail +{ + +template +struct radius_access +{ + static inline typename radius_type::type get(Geometry const& geometry) + { + return traits::radius_access::get(geometry); + } + static inline void set(Geometry& geometry, + typename radius_type::type const& value) + { + traits::radius_access::set(geometry, value); + } +}; + +} // namespace detail +#endif // DOXYGEN_NO_DETAIL + + +#ifndef DOXYGEN_NO_DISPATCH +namespace core_dispatch +{ + +template +struct radius_access +{ + typedef typename geometry::radius_type::type radius_type; + + static inline radius_type get(const Geometry * geometry) + { + return radius_access + < + Tag, + Geometry, + Dimension, + typename boost::is_pointer::type + >::get(*geometry); + } + + static inline void set(Geometry * geometry, radius_type const& value) + { + return radius_access + < + Tag, + Geometry, + Dimension, + typename boost::is_pointer::type + >::set(*geometry, value); + } +}; + + +template +struct radius_type +{ + typedef typename traits::radius_type::type type; +}; + +template +struct radius_access + : detail::radius_access +{ + BOOST_STATIC_ASSERT(Dimension == 0); + //BOOST_STATIC_ASSERT(Dimension < 3); +}; + +template +struct radius_type +{ + typedef typename traits::radius_type::type type; +}; + +template +struct radius_access + : detail::radius_access +{ + BOOST_STATIC_ASSERT(Dimension == 0 || Dimension == 2); + //BOOST_STATIC_ASSERT(Dimension < 3); +}; + +} // namespace core_dispatch +#endif // DOXYGEN_NO_DISPATCH + + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_CORE_RADIUS_HPP diff --git a/include/boost/geometry/core/srs.hpp b/include/boost/geometry/core/srs.hpp new file mode 100644 index 000000000..bf1b4e28a --- /dev/null +++ b/include/boost/geometry/core/srs.hpp @@ -0,0 +1,195 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2008-2012 Bruno Lalande, Paris, France. +// Copyright (c) 2009-2012 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 Adam Wulkiewicz, 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_CORE_SRS_HPP +#define BOOST_GEOMETRY_CORE_SRS_HPP + + +#include + +#include + +#include +#include +#include + + +namespace boost { namespace geometry +{ + +namespace srs +{ + +/*! + \brief Defines spheroid radius values for use in geographical CS calculations + \note See http://en.wikipedia.org/wiki/Figure_of_the_Earth + and http://en.wikipedia.org/wiki/World_Geodetic_System#A_new_World_Geodetic_System:_WGS84 +*/ +template +class spheroid +{ +public: + spheroid(RadiusType const& a, RadiusType const& b) + : m_a(a) + , m_b(b) + {} + + spheroid() + : m_a(RadiusType(6378137.0)) + , m_b(RadiusType(6356752.314245)) + {} + + template + RadiusType get_radius() const + { + BOOST_STATIC_ASSERT(I < 3); + + return I < 2 ? m_a : m_b; + } + + template + void set_radius(RadiusType const& radius) + { + BOOST_STATIC_ASSERT(I < 3); + + (I < 2 ? m_a : m_b) = radius; + } + +private: + RadiusType m_a, m_b; // equatorial radius, polar radius +}; + +} // namespace srs + +// Traits specializations for spheroid +#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS +namespace traits +{ + +template +struct tag< srs::spheroid > +{ + typedef srs_spheroid_tag type; +}; + +template +struct radius_type< srs::spheroid > +{ + typedef RadiusType type; +}; + +template +struct radius_access, Dimension> +{ + typedef srs::spheroid spheroid_type; + + static inline RadiusType get(spheroid_type const& s) + { + return s.template get_radius(); + } + + static inline void set(spheroid_type& s, RadiusType const& value) + { + s.template set_radius(value); + } +}; + +} // namespace traits +#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS + + +namespace srs +{ + +/*! + \brief Defines sphere radius value for use in spherical CS calculations +*/ +template +class sphere +{ +public: + explicit sphere(RadiusType const& r) + : m_r(r) + {} + sphere() + : m_r(RadiusType((2.0 * 6378137.0 + 6356752.314245) / 3.0)) + {} + + template + RadiusType get_radius() const + { + BOOST_STATIC_ASSERT(I < 3); + + return m_r; + } + + template + void set_radius(RadiusType const& radius) + { + BOOST_STATIC_ASSERT(I < 3); + + m_r = radius; + } + +private: + RadiusType m_r; // radius +}; + +} // namespace srs + +// Traits specializations for sphere +#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS +namespace traits +{ + +template +struct tag< srs::sphere > +{ + typedef srs_sphere_tag type; +}; + +template +struct radius_type< srs::sphere > +{ + typedef RadiusType type; +}; + +template +struct radius_access, Dimension> +{ + typedef srs::sphere sphere_type; + + static inline RadiusType get(sphere_type const& s) + { + return s.template get_radius(); + } + + static inline void set(sphere_type& s, RadiusType const& value) + { + s.template set_radius(value); + } +}; + +} // namespace traits +#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS + + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_CORE_SRS_HPP diff --git a/include/boost/geometry/core/tags.hpp b/include/boost/geometry/core/tags.hpp index 160477b8c..5d6acb187 100644 --- a/include/boost/geometry/core/tags.hpp +++ b/include/boost/geometry/core/tags.hpp @@ -4,6 +4,11 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 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 Adam Wulkiewicz, 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. @@ -37,6 +42,14 @@ struct spherical_equatorial_tag : spherical_tag {}; struct geographic_tag : spherical_tag {}; +// Tags defining coordinate systems reference models + +/// For reference spheroid defining parameters of geographical coordinate system +struct srs_spheroid_tag {}; + +/// For reference sphere defining parameters of spherical coordinate system +struct srs_sphere_tag : srs_spheroid_tag {}; + // Tags defining tag hierarchy diff --git a/include/boost/geometry/extensions/gis/geographic/detail/ellipsoid.hpp b/include/boost/geometry/extensions/gis/geographic/detail/ellipsoid.hpp deleted file mode 100644 index a2b7b4703..000000000 --- a/include/boost/geometry/extensions/gis/geographic/detail/ellipsoid.hpp +++ /dev/null @@ -1,60 +0,0 @@ -// Boost.Geometry (aka GGL, Generic Geometry Library) - -// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// Copyright (c) 2008-2012 Bruno Lalande, Paris, France. -// Copyright (c) 2009-2012 Mateusz Loskot, London, UK. - -// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library -// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. - -// Use, modification and distribution is subject to the Boost Software License, -// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_GEOMETRY_EXTENSIONS_GIS_GEOGRAPHIC_DETAIL_ELLIPSOID_HPP -#define BOOST_GEOMETRY_EXTENSIONS_GIS_GEOGRAPHIC_DETAIL_ELLIPSOID_HPP - - -namespace boost { namespace geometry { namespace detail -{ - - -/*! - \brief Defines ellipsoid values for use in distance calculations - \details They have a constructor with the earth radius - \note Will be moved / merged with projections - \todo Optionally specify earth model, defaulting to WGS84 - - See http://en.wikipedia.org/wiki/Figure_of_the_Earth - - and http://en.wikipedia.org/wiki/World_Geodetic_System#A_new_World_Geodetic_System:_WGS84 - \note -*/ -template -class ellipsoid -{ - public : - ellipsoid(T const& a, T const& b) - : m_a(a) - , m_b(b) - , m_f((a - b) / a) - {} - ellipsoid() - : m_a(T(6378137.0)) - , m_b(T(6356752.314245)) - , m_f((m_a - m_b) / m_a) - {} - - T a() const { return m_a; } - T b() const { return m_b; } - T f() const { return m_f; } - - private : - T m_a, m_b, m_f; // equatorial radius, polar radius, flattening -}; - - - - -}}} // namespace boost::geometry::detail - - -#endif // BOOST_GEOMETRY_EXTENSIONS_GIS_GEOGRAPHIC_DETAIL_ELLIPSOID_HPP diff --git a/include/boost/geometry/extensions/gis/geographic/strategies/andoyer.hpp b/include/boost/geometry/extensions/gis/geographic/strategies/andoyer.hpp index b20a9aa0a..d8a19d439 100644 --- a/include/boost/geometry/extensions/gis/geographic/strategies/andoyer.hpp +++ b/include/boost/geometry/extensions/gis/geographic/strategies/andoyer.hpp @@ -2,6 +2,11 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2014. +// Modifications copyright (c) 2014 Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // 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) @@ -10,14 +15,18 @@ #define BOOST_GEOMETRY_EXTENSIONS_GIS_GEOGRAPHIC_STRATEGIES_ANDOYER_HPP -#include -#include #include -#include -#include -#include +#include +#include +#include -#include +#include + +#include + +#include +#include +#include namespace boost { namespace geometry @@ -44,7 +53,7 @@ are about the same as Vincenty. In my (Barend's) testcases the results didn't di */ template < - typename RadiusType, + typename Spheroid, typename CalculationType = void > class andoyer @@ -63,14 +72,14 @@ public : > {}; - typedef RadiusType radius_type; + typedef Spheroid model_type; inline andoyer() - : m_ellipsoid() + : m_spheroid() {} - explicit inline andoyer(geometry::detail::ellipsoid const& e) - : m_ellipsoid(e) + explicit inline andoyer(Spheroid const& spheroid) + : m_spheroid(spheroid) {} @@ -85,20 +94,12 @@ public : ); } - inline geometry::detail::ellipsoid ellipsoid() const + inline Spheroid const& model() const { - return m_ellipsoid; + return m_spheroid; } - inline RadiusType radius() const - { - return m_ellipsoid.a(); - } - - private : - geometry::detail::ellipsoid m_ellipsoid; - template inline CT calc(T const& lon1, T const& lat1, @@ -136,15 +137,19 @@ private : return c0; } + CT const radius_a = CT(get_radius<0>(m_spheroid)); + CT const flattening = geometry::detail::flattening(m_spheroid); + CT const omega = atan(math::sqrt(S / C)); CT const r3 = c3 * math::sqrt(S * C) / omega; // not sure if this is r or greek nu - CT const D = c2 * omega * m_ellipsoid.a(); + CT const D = c2 * omega * radius_a; CT const H1 = (r3 - c1) / (c2 * C); CT const H2 = (r3 + c1) / (c2 * S); - CT const f = m_ellipsoid.f(); - return D * (c1 + f * H1 * sinF2 * cosG2 - f * H2 * cosF2 * sinG2); + return D * (c1 + flattening * (H1 * sinF2 * cosG2 - H2 * cosF2 * sinG2) ); } + + Spheroid m_spheroid; }; @@ -152,41 +157,41 @@ private : namespace services { -template -struct tag > +template +struct tag > { typedef strategy_tag_distance_point_point type; }; -template -struct return_type, P1, P2> - : andoyer::template calculation_type +template +struct return_type, P1, P2> + : andoyer::template calculation_type {}; -template -struct comparable_type > +template +struct comparable_type > { - typedef andoyer type; + typedef andoyer type; }; -template -struct get_comparable > +template +struct get_comparable > { - static inline andoyer apply(andoyer const& input) + static inline andoyer apply(andoyer const& input) { return input; } }; -template -struct result_from_distance, P1, P2> +template +struct result_from_distance, P1, P2> { template - static inline typename return_type, P1, P2>::type - apply(andoyer const& , T const& value) + static inline typename return_type, P1, P2>::type + apply(andoyer const& , T const& value) { return value; } @@ -196,7 +201,13 @@ struct result_from_distance, P1, P2> template struct default_strategy { - typedef strategy::distance::andoyer::type> type; + typedef strategy::distance::andoyer + < + srs::spheroid + < + typename select_coordinate_type::type + > + > type; }; diff --git a/include/boost/geometry/extensions/gis/geographic/strategies/vincenty.hpp b/include/boost/geometry/extensions/gis/geographic/strategies/vincenty.hpp index fd8ae64bb..4ac3c5c3e 100644 --- a/include/boost/geometry/extensions/gis/geographic/strategies/vincenty.hpp +++ b/include/boost/geometry/extensions/gis/geographic/strategies/vincenty.hpp @@ -2,6 +2,11 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2014. +// Modifications copyright (c) 2014 Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // 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) @@ -9,19 +14,20 @@ #ifndef BOOST_GEOMETRY_EXTENSIONS_GIS_GEOGRAPHIC_STRATEGIES_VINCENTY_HPP #define BOOST_GEOMETRY_EXTENSIONS_GIS_GEOGRAPHIC_STRATEGIES_VINCENTY_HPP + #include +#include +#include +#include + +#include #include -#include -#include -#include -#include + #include - -#include - - +#include +#include namespace boost { namespace geometry @@ -45,7 +51,7 @@ namespace strategy { namespace distance */ template < - typename RadiusType, + typename Spheroid, typename CalculationType = void > class vincenty @@ -64,13 +70,14 @@ public : > {}; - typedef RadiusType radius_type; + typedef Spheroid model_type; inline vincenty() + : m_spheroid() {} - explicit inline vincenty(geometry::detail::ellipsoid const& e) - : m_ellipsoid(e) + explicit inline vincenty(Spheroid const& spheroid) + : m_spheroid(spheroid) {} template @@ -84,25 +91,17 @@ public : ); } - inline geometry::detail::ellipsoid ellipsoid() const + inline Spheroid const& model() const { - return m_ellipsoid; - } - - inline RadiusType radius() const - { - // For now return the major axis. It is used in distance_cross_track, from point-to-line - return m_ellipsoid.a(); + return m_spheroid; } private : - geometry::detail::ellipsoid m_ellipsoid; - template inline CT calculate(T const& lon1, - T const& lat1, - T const& lon2, - T const& lat2) const + T const& lat1, + T const& lon2, + T const& lat2) const { CT const c2 = 2; CT const pi = geometry::math::pi(); @@ -120,9 +119,13 @@ private : return CT(0); } + CT const radius_a = CT(get_radius<0>(m_spheroid)); + CT const radius_b = CT(get_radius<2>(m_spheroid)); + CT const flattening = geometry::detail::flattening(m_spheroid); + // U: reduced latitude, defined by tan U = (1-f) tan phi CT const c1 = 1; - CT const one_min_f = c1 - m_ellipsoid.f(); + CT const one_min_f = c1 - flattening; CT const U1 = atan(one_min_f * tan(lat1)); // above (1) CT const U2 = atan(one_min_f * tan(lat2)); // above (1) @@ -150,7 +153,7 @@ private : CT const c6 = 6; CT const c16 = 16; - CT const c_e_12 = 1e-12; + CT const c_e_12 = CT(1e-12); do { @@ -163,15 +166,15 @@ private : cos2_alpha = c1 - math::sqr(sin_alpha); cos2_sigma_m = math::equals(cos2_alpha, 0) ? 0 : cos_sigma - c2 * sin_U1 * sin_U2 / cos2_alpha; // (18) - CT C = m_ellipsoid.f()/c16 * cos2_alpha * (c4 + m_ellipsoid.f() * (c4 - c3 * cos2_alpha)); // (10) + CT C = flattening/c16 * cos2_alpha * (c4 + flattening * (c4 - c3 * cos2_alpha)); // (10) sigma = atan2(sin_sigma, cos_sigma); // (16) - lambda = L + (c1 - C) * m_ellipsoid.f() * sin_alpha * + lambda = L + (c1 - C) * flattening * sin_alpha * (sigma + C * sin_sigma * ( cos2_sigma_m + C * cos_sigma * (-c1 + c2 * math::sqr(cos2_sigma_m)))); // (11) } while (geometry::math::abs(previous_lambda - lambda) > c_e_12 && geometry::math::abs(lambda) < pi); - CT sqr_u = cos2_alpha * (math::sqr(m_ellipsoid.a()) - math::sqr(m_ellipsoid.b())) / math::sqr(m_ellipsoid.b()); // above (1) + CT sqr_u = cos2_alpha * (math::sqr(radius_a) - math::sqr(radius_b)) / math::sqr(radius_b); // above (1) // Oops getting hard here // (again, problem is that ttmath cannot divide by doubles, which is OK) @@ -191,49 +194,51 @@ private : CT delta_sigma = B * sin_sigma * ( cos2_sigma_m + (B/c4) * (cos(sigma)* (-c1 + c2 * cos2_sigma_m) - (B/c6) * cos2_sigma_m * (-c3 + c4 * math::sqr(sin_sigma)) * (-c3 + c4 * cos2_sigma_m))); // (6) - return m_ellipsoid.b() * A * (sigma - delta_sigma); // (19) + return radius_b * A * (sigma - delta_sigma); // (19) } + + Spheroid m_spheroid; }; #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS namespace services { -template -struct tag > +template +struct tag > { typedef strategy_tag_distance_point_point type; }; -template -struct return_type, P1, P2> - : vincenty::template calculation_type +template +struct return_type, P1, P2> + : vincenty::template calculation_type {}; -template -struct comparable_type > +template +struct comparable_type > { - typedef vincenty type; + typedef vincenty type; }; -template -struct get_comparable > +template +struct get_comparable > { - static inline vincenty apply(vincenty const& input) + static inline vincenty apply(vincenty const& input) { return input; } }; -template -struct result_from_distance, P1, P2 > +template +struct result_from_distance, P1, P2 > { template - static inline typename return_type, P1, P2>::type - apply(vincenty const& , T const& value) + static inline typename return_type, P1, P2>::type + apply(vincenty const& , T const& value) { return value; } diff --git a/include/boost/geometry/extensions/nsphere/core/radius.hpp b/include/boost/geometry/extensions/nsphere/core/radius.hpp index 2e3e8704a..331b7243a 100644 --- a/include/boost/geometry/extensions/nsphere/core/radius.hpp +++ b/include/boost/geometry/extensions/nsphere/core/radius.hpp @@ -4,6 +4,11 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 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 Adam Wulkiewicz, 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. @@ -19,9 +24,7 @@ #include -#include - -#include +#include #include @@ -29,129 +32,28 @@ namespace boost { namespace geometry { -namespace traits -{ - -/*! - \brief Traits class to get/set radius of a circle/sphere/(ellipse) - \details the radius access meta-functions give read/write access to the radius of a circle or a sphere, - or to the major/minor axis or an ellipse, or to one of the 3 equatorial radii of an ellipsoid. - - It should be specialized per geometry, in namespace core_dispatch. Those specializations should - forward the call via traits to the geometry class, which could be specified by the user. - - There is a corresponding generic radius_get and radius_set function - \par Geometries: - - n-sphere (circle,sphere) - - upcoming ellipse - \par Specializations should provide: - - inline static T get(G const& geometry) - - inline static void set(G& geometry, T const& radius) - \ingroup traits -*/ -template -struct radius_access {}; - - -/*! - \brief Traits class indicating the type (double,float,...) of the radius of a circle or a sphere - \par Geometries: - - n-sphere (circle,sphere) - - upcoming ellipse - \par Specializations should provide: - - typedef T type (double,float,int,etc) - \ingroup traits -*/ -template -struct radius_type {}; - -} // namespace traits - #ifndef DOXYGEN_NO_DISPATCH namespace core_dispatch { -template -struct radius_type -{ - //typedef core_dispatch_specialization_required type; -}; - -/*! - \brief radius access meta-functions, used by concept n-sphere and upcoming ellipse. -*/ -template -struct radius_access -{ - //static inline T get(G const& ) {} - //static inline void set(G& g, T const& value) {} -}; - template struct radius_type { typedef typename traits::radius_type::type type; }; -template -struct radius_access +template +struct radius_access + : detail::radius_access { BOOST_STATIC_ASSERT((D == 0)); - static inline T get(S const& s) - { - return traits::radius_access::get(s); - } - static inline void set(S& s, T const& radius) - { - traits::radius_access::set(s, radius); - } }; } // namespace core_dispatch #endif // DOXYGEN_NO_DISPATCH -template -struct radius_type -{ - typedef typename boost::remove_const::type rconst; - typedef typename core_dispatch::radius_type::type, rconst>::type type; -}; - -/*! - \brief Function to get radius - \return radius of a circle / sphere / ellipse - \ingroup access - \param geometry the geometry to get the radius from - \tparam I index, for circle/sphere always zero, for ellipse major/minor axis, - for ellipsoid one of the 3 equatorial radii -*/ -template -inline typename radius_type::type get_radius(G const& geometry) -{ - typedef typename boost::remove_const::type rconst; - - return core_dispatch::radius_access::type, rconst, - typename radius_type::type, I>::get(geometry); -} - -/*! - \brief Function to set the radius of a circle / sphere / (ellipse) - \ingroup access - \tparam I index, for circle/sphere always zero, for ellipse major/minor axis, - for ellipsoid one of the 3 equatorial radii - \param geometry the geometry to change - \param radius the radius to set -*/ -template -inline void set_radius(G& geometry, typename radius_type::type const& radius) -{ - core_dispatch::radius_access::type, G, - typename radius_type::type, I>::set(geometry, radius); -} - - }} // namespace boost::geometry diff --git a/include/boost/geometry/extensions/nsphere/geometries/nsphere.hpp b/include/boost/geometry/extensions/nsphere/geometries/nsphere.hpp index db4080fc8..4f7cb72b3 100644 --- a/include/boost/geometry/extensions/nsphere/geometries/nsphere.hpp +++ b/include/boost/geometry/extensions/nsphere/geometries/nsphere.hpp @@ -121,7 +121,7 @@ struct access, Dimension> }; template -struct radius_access, RadiusType, 0> +struct radius_access, 0> { typedef model::nsphere nsphere_type; diff --git a/include/boost/geometry/geometry.hpp b/include/boost/geometry/geometry.hpp index 110f0e60f..cf16ef7d9 100644 --- a/include/boost/geometry/geometry.hpp +++ b/include/boost/geometry/geometry.hpp @@ -4,6 +4,11 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 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 Adam Wulkiewicz, 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. @@ -25,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -34,9 +40,9 @@ #include #include #include +#include #include - #include #include diff --git a/include/boost/geometry/io/wkt/read.hpp b/include/boost/geometry/io/wkt/read.hpp index 748eecdbe..5fa2e1560 100644 --- a/include/boost/geometry/io/wkt/read.hpp +++ b/include/boost/geometry/io/wkt/read.hpp @@ -4,6 +4,11 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 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 Adam Wulkiewicz, 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. @@ -29,6 +34,7 @@ #include #include #include +#include #include #include @@ -38,6 +44,7 @@ #include #include #include +#include #include #include @@ -98,7 +105,9 @@ namespace detail { namespace wkt typedef boost::tokenizer > tokenizer; -template +template ::value> struct parsing_assigner { static inline void apply(tokenizer::iterator& it, tokenizer::iterator end, @@ -208,12 +217,7 @@ struct container_inserter while (it != end && *it != ")") { - parsing_assigner - < - Point, - 0, - dimension::value - >::apply(it, end, point, wkt); + parsing_assigner::apply(it, end, point, wkt); out = point; ++out; if (it != end && *it == ",") @@ -227,35 +231,94 @@ struct container_inserter }; +template ::value> +struct stateful_range_appender +{ + typedef typename geometry::point_type::type point_type; + + // NOTE: Geometry is a reference + inline void append(Geometry geom, point_type const& point, bool) + { + geometry::append(geom, point); + } +}; + +template +struct stateful_range_appender +{ + typedef typename geometry::point_type::type point_type; + typedef typename boost::range_size + < + typename util::bare_type::type + >::type size_type; + + BOOST_STATIC_ASSERT(( boost::is_same + < + typename tag::type, + ring_tag + >::value )); + + inline stateful_range_appender() + : pt_index(0) + {} + + // NOTE: Geometry is a reference + inline void append(Geometry geom, point_type const& point, bool is_next_expected) + { + bool should_append = true; + + if ( pt_index == 0 ) + { + first_point = point; + //should_append = true; + } + else + { + // NOTE: if there is not enough Points, they're always appended + should_append + = is_next_expected + || pt_index < core_detail::closure::minimum_ring_size::value + || !detail::equals::equals_point_point(point, first_point); + } + ++pt_index; + + if ( should_append ) + { + geometry::append(geom, point); + } + } + +private: + size_type pt_index; + point_type first_point; +}; + // Geometry is a value-type or reference-type template struct container_appender { - typedef typename geometry::point_type - < - typename boost::remove_reference::type - >::type point_type; + typedef typename geometry::point_type::type point_type; static inline void apply(tokenizer::iterator& it, tokenizer::iterator end, - std::string const& wkt, Geometry out) + std::string const& wkt, Geometry out) { handle_open_parenthesis(it, end, wkt); - point_type point; + stateful_range_appender appender; // Parse points until closing parenthesis - while (it != end && *it != ")") { - parsing_assigner - < - point_type, - 0, - dimension::value - >::apply(it, end, point, wkt); + point_type point; - geometry::append(out, point); - if (it != end && *it == ",") + parsing_assigner::apply(it, end, point, wkt); + + bool const is_next_expected = it != end && *it == ","; + + appender.append(out, point, is_next_expected); + + if ( is_next_expected ) { ++it; } @@ -276,7 +339,7 @@ struct point_parser std::string const& wkt, P& point) { handle_open_parenthesis(it, end, wkt); - parsing_assigner::value>::apply(it, end, point, wkt); + parsing_assigner

::apply(it, end, point, wkt); handle_close_parenthesis(it, end, wkt); } }; @@ -512,7 +575,7 @@ struct noparenthesis_point_parser static inline void apply(tokenizer::iterator& it, tokenizer::iterator end, std::string const& wkt, P& point) { - parsing_assigner::value>::apply(it, end, point, wkt); + parsing_assigner

::apply(it, end, point, wkt); } }; diff --git a/index/test/rtree/exceptions/test_throwing_node.hpp b/index/test/rtree/exceptions/test_throwing_node.hpp index d32c6bcca..4aa0ef750 100644 --- a/index/test/rtree/exceptions/test_throwing_node.hpp +++ b/index/test/rtree/exceptions/test_throwing_node.hpp @@ -174,9 +174,13 @@ struct visitor -struct allocators +class allocators : public Allocator::template rebind< - typename node, node_throwing_static_tag>::type + typename node< + Value, Parameters, Box, + allocators, + node_throwing_static_tag + >::type >::other { typedef typename Allocator::template rebind< diff --git a/test/algorithms/is_valid.cpp b/test/algorithms/is_valid.cpp index 78c290556..60f98057d 100644 --- a/test/algorithms/is_valid.cpp +++ b/test/algorithms/is_valid.cpp @@ -280,7 +280,7 @@ void test_open_rings() test::apply(from_wkt("POLYGON((0 0,0 0,0 0))"), false); test::apply(from_wkt("POLYGON((0 0,1 0,1 0))"), false); test::apply(from_wkt("POLYGON((0 0,1 0,0 0))"), false); - test::apply(from_wkt("POLYGON((0 0,1 0,1 1,0 0))"), + test::apply(from_wkt("POLYGON((0 0,1 0,1 1,0 0,0 0))"), AllowDuplicates); test::apply(from_wkt("POLYGON((0 0,1 0,1 0,1 1))"), AllowDuplicates); @@ -426,7 +426,7 @@ void test_open_polygons() test::apply(from_wkt("POLYGON((0 0,0 0,0 0))"), false); test::apply(from_wkt("POLYGON((0 0,1 0,1 0))"), false); test::apply(from_wkt("POLYGON((0 0,1 0,0 0))"), false); - test::apply(from_wkt("POLYGON((0 0,1 0,1 1,0 0))"), AllowDuplicates); + test::apply(from_wkt("POLYGON((0 0,1 0,1 1,0 0,0 0))"), AllowDuplicates); test::apply(from_wkt("POLYGON((0 0,1 0,1 0,1 1))"), AllowDuplicates); test::apply(from_wkt("POLYGON((0 0,1 0,1 0,1 1,0 0))"), AllowDuplicates); @@ -438,7 +438,7 @@ void test_open_polygons() false); test::apply(from_wkt("POLYGON((0 0,10 0,10 10,0 10),(1 1,2 1,1 1))"), false); - test::apply(from_wkt("POLYGON((0 0,10 0,10 10,0 10),(1 1,2 2,2 1,1 1))"), + test::apply(from_wkt("POLYGON((0 0,10 0,10 10,0 10),(1 1,2 2,2 1,1 1,1 1))"), AllowDuplicates); test::apply(from_wkt("POLYGON((0 0,10 0,10 10,0 10),(1 1,2 2,2 2,2 1))"), AllowDuplicates); diff --git a/test/algorithms/num_points.cpp b/test/algorithms/num_points.cpp index d1f58b299..1c266d8af 100644 --- a/test/algorithms/num_points.cpp +++ b/test/algorithms/num_points.cpp @@ -86,11 +86,11 @@ int test_main(int, char* []) // test open geometries test_num_points("POLYGON((0 0,1 1,0 1))", 3u, 4u); - test_num_points("POLYGON((0 0,1 1,0 1,0 0))", 4u, 5u); + test_num_points("POLYGON((0 0,1 1,0 1,0 0))", 3u, 4u); test_num_points("POLYGON((0 0,10 10,0 10))", 3u, 4u); - test_num_points("POLYGON((0 0,10 10,0 10,0 0))", 4u, 5u); + test_num_points("POLYGON((0 0,10 10,0 10,0 0))", 3u, 4u); test_num_points("MULTIPOLYGON(((0 0,0 10,10 10,10 0)),((0 10,1 10,1 9)))", 7u, 9u); - test_num_points("MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0)),((0 10,1 10,1 9,0 10)))", 9u, 11u); + test_num_points("MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0)),((0 10,1 10,1 9,0 10)))", 7u, 9u); return 0; } diff --git a/test/algorithms/relational_operations/within/test_within.hpp b/test/algorithms/relational_operations/within/test_within.hpp index da402a07c..0fc3b1b01 100644 --- a/test/algorithms/relational_operations/within/test_within.hpp +++ b/test/algorithms/relational_operations/within/test_within.hpp @@ -88,10 +88,6 @@ void test_ordered_ring(std::string const& wkt_point, { std::reverse(boost::begin(ring), boost::end(ring)); } - if (! Closed) - { - ring.resize(ring.size() - 1); - } bg::read_wkt(wkt_point, point); diff --git a/test/core/Jamfile.v2 b/test/core/Jamfile.v2 index 398d1e025..613174f15 100644 --- a/test/core/Jamfile.v2 +++ b/test/core/Jamfile.v2 @@ -17,6 +17,7 @@ test-suite boost-geometry-core [ run geometry_id.cpp ] [ run point_type.cpp ] [ run radian_access.cpp ] + [ run radius.cpp ] # [ run reverse_dispatch.cpp ] [ run ring.cpp ] [ run tag.cpp ] diff --git a/test/core/radius.cpp b/test/core/radius.cpp new file mode 100644 index 000000000..11f81a5e7 --- /dev/null +++ b/test/core/radius.cpp @@ -0,0 +1,62 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) +// Unit Test + +// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2008-2012 Bruno Lalande, Paris, France. +// Copyright (c) 2009-2012 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 Adam Wulkiewicz, 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) + + +#include + +#include +#include +#include + +#include + + +template +void test_get_set() +{ + typedef typename bg::radius_type::type radius_type; + + G g; + bg::set_radius(g, radius_type(5)); + + radius_type x = bg::get_radius(g); + + BOOST_CHECK_CLOSE(double(x), 5.0, 0.0001); +} + +template +void test_all() +{ + typedef bg::srs::spheroid Sd; + test_get_set<0, Sd>(); + test_get_set<2, Sd>(); + + typedef bg::srs::sphere Se; + test_get_set<0, Se>(); +} + + +int test_main(int, char* []) +{ + test_all(); + test_all(); + test_all(); + + return 0; +} diff --git a/test/io/wkt/multi_wkt.cpp b/test/io/wkt/multi_wkt.cpp index 317f0578c..35265feee 100644 --- a/test/io/wkt/multi_wkt.cpp +++ b/test/io/wkt/multi_wkt.cpp @@ -5,6 +5,11 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 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 Adam Wulkiewicz, 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. @@ -45,6 +50,33 @@ void test_all(); #define GEOMETRY_TEST_MULTI #include "io/wkt/wkt.cpp" +template +void test_order_closure() +{ + using namespace boost::geometry; + typedef bg::model::point Pt; + typedef bg::model::polygon PCWC; + typedef bg::model::polygon PCWO; + typedef bg::model::polygon PCCWC; + typedef bg::model::polygon PCCWO; + typedef bg::model::multi_polygon MPCWC; + typedef bg::model::multi_polygon MPCWO; + typedef bg::model::multi_polygon MPCCWC; + typedef bg::model::multi_polygon MPCCWO; + + std::string wkt_cwc = "MULTIPOLYGON(((0 0,0 2,2 2,2 0,0 0)),((0 0,0 -3,-3 -3,-3 0,0 0),(-1 -1,-2 -1,-2 -2,-1 -2,-1 -1)))"; + std::string wkt_cwo = "MULTIPOLYGON(((0 0,0 2,2 2,2 0)),((0 0,0 -3,-3 -3,-3 0),(-1 -1,-2 -1,-2 -2,-1 -2)))"; + std::string wkt_ccwc = "MULTIPOLYGON(((0 0,2 0,2 2,0 2,0 0)),((0 0,-3 0,-3 -3,0 -3,0 0),(-1 -1,-1 -2,-2 -2,-2 -1,-1 -1)))"; + std::string wkt_ccwo = "MULTIPOLYGON(((0 0,2 0,2 2,0 2)),((0 0,-3 0,-3 -3,0 -3),(-1 -1,-1 -2,-2 -2,-2 -1)))"; + + test_wkt(wkt_cwc, wkt_cwc, 15, 0, 12, 24); + test_wkt(wkt_cwc, wkt_cwc, 12, 0, 12, 24); + test_wkt(wkt_cwo, wkt_cwc, 12, 0, 12, 24); + test_wkt(wkt_ccwc, wkt_ccwc, 15, 0, 12, 24); + test_wkt(wkt_ccwc, wkt_ccwc, 12, 0, 12, 24); + test_wkt(wkt_ccwo, wkt_ccwc, 12, 0, 12, 24); +} + template void test_all() { @@ -79,6 +111,8 @@ void test_all() test_wrong_wkt >( "MULTIPOINT(16 17), (18 19)", "too much tokens at ',' in 'multipoint(16 17), (18 19)'"); + + test_order_closure(); } /* diff --git a/test/io/wkt/wkt.cpp b/test/io/wkt/wkt.cpp index 72badd383..40fb04acf 100644 --- a/test/io/wkt/wkt.cpp +++ b/test/io/wkt/wkt.cpp @@ -5,6 +5,11 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 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 Adam Wulkiewicz, 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. @@ -42,8 +47,8 @@ void check_wkt(G const& geometry, std::string const& expected) } template -void test_wkt(std::string const& wkt, std::size_t n, double len = 0, - double ar = 0, double peri = 0) +void test_wkt(std::string const& wkt, std::string const& expected, + std::size_t n, double len = 0, double ar = 0, double peri = 0) { G geometry; @@ -67,8 +72,15 @@ void test_wkt(std::string const& wkt, std::size_t n, double len = 0, BOOST_CHECK_CLOSE(double(bg::perimeter(geometry)), peri, 0.0001); } - check_wkt(geometry, wkt); - check_wkt(boost::variant(geometry), wkt); + check_wkt(geometry, expected); + check_wkt(boost::variant(geometry), expected); +} + +template +void test_wkt(std::string const& wkt, + std::size_t n, double len = 0, double ar = 0, double peri = 0) +{ + test_wkt(wkt, wkt, n, len, ar, peri); } template @@ -135,6 +147,44 @@ void test_wkt_output_iterator(std::string const& wkt) #ifndef GEOMETRY_TEST_MULTI +template +void test_order_closure() +{ + using namespace boost::geometry; + typedef bg::model::point Pt; + typedef bg::model::polygon PCWC; + typedef bg::model::polygon PCWO; + typedef bg::model::polygon PCCWC; + typedef bg::model::polygon PCCWO; + + { + std::string wkt_cwc = "POLYGON((0 0,0 2,2 2,2 0,0 0))"; + std::string wkt_cwo = "POLYGON((0 0,0 2,2 2,2 0))"; + std::string wkt_ccwc = "POLYGON((0 0,2 0,2 2,0 2,0 0))"; + std::string wkt_ccwo = "POLYGON((0 0,2 0,2 2,0 2))"; + + test_wkt(wkt_cwc, 5, 0, 4, 8); + test_wkt(wkt_cwc, 4, 0, 4, 8); + test_wkt(wkt_cwo, wkt_cwc, 4, 0, 4, 8); + test_wkt(wkt_ccwc, 5, 0, 4, 8); + test_wkt(wkt_ccwc, 4, 0, 4, 8); + test_wkt(wkt_ccwo, wkt_ccwc, 4, 0, 4, 8); + } + { + std::string wkt_cwc = "POLYGON((0 0,0 3,3 3,3 0,0 0),(1 1,2 1,2 2,1 2,1 1))"; + std::string wkt_cwo = "POLYGON((0 0,0 3,3 3,3 0),(1 1,2 1,2 2,1 2))"; + std::string wkt_ccwc = "POLYGON((0 0,3 0,3 3,0 3,0 0),(1 1,1 2,2 2,2 1,1 1))"; + std::string wkt_ccwo = "POLYGON((0 0,3 0,3 3,0 3),(1 1,1 2,2 2,2 1,1 1))"; + + test_wkt(wkt_cwc, 10, 0, 8, 16); + test_wkt(wkt_cwc, 8, 0, 8, 16); + test_wkt(wkt_cwo, wkt_cwc, 8, 0, 8, 16); + test_wkt(wkt_ccwc, 10, 0, 8, 16); + test_wkt(wkt_ccwc, 8, 0, 8, 16); + test_wkt(wkt_ccwo, wkt_ccwc, 8, 0, 8, 16); + } +} + template void test_all() { @@ -201,10 +251,11 @@ void test_all() // Deprecated: // test_wkt_output_iterator >("LINESTRING(1 1,2 2,3 3)"); // test_wkt_output_iterator >("POLYGON((1 1,2 2,3 3))"); + + test_order_closure(); } #endif - int test_main(int, char* []) { test_all();